* zf3 version bump

* SSO auth added to the site
This commit is contained in:
Dávid Danyi
2018-07-25 18:20:45 +02:00
parent 4c0badd7bc
commit 0d5299c7b7
15 changed files with 1647 additions and 864 deletions

View File

@@ -2,17 +2,17 @@
namespace App\Action;
use Interop\Http\ServerMiddleware\DelegateInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response\JsonResponse;
use Zend\Json\Json;
abstract class AbstractAction implements ServerMiddlewareInterface
abstract class AbstractAction implements RequestHandlerInterface
{
const IDENTIFIER_NAME = 'id';
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$requestMethod = strtoupper($request->getMethod());
$id = $request->getAttribute(static::IDENTIFIER_NAME);
@@ -20,73 +20,73 @@ abstract class AbstractAction implements ServerMiddlewareInterface
switch ($requestMethod) {
case 'GET':
return isset($id)
? $this->get($request, $delegate)
: $this->getList($request, $delegate);
? $this->get($request)
: $this->getList($request);
case 'POST':
return $this->create($request, $delegate);
return $this->create($request);
case 'PUT':
return $this->update($request, $delegate);
return $this->update($request);
case 'DELETE':
return isset($id)
? $this->delete($request, $delegate)
: $this->deleteList($request, $delegate);
? $this->delete($request)
: $this->deleteList($request);
case 'HEAD':
return $this->head($request, $delegate);
return $this->head($request);
case 'OPTIONS':
return $this->options($request, $delegate);
return $this->options($request);
case 'PATCH':
return $this->patch($request, $delegate);
return $this->patch($request);
default:
return $delegate->process($request);
die(500);
}
}
public function get(ServerRequestInterface $request, DelegateInterface $delegate)
public function get(ServerRequestInterface $request) : ResponseInterface
{
return $this->createResponse(['content' => 'Method not allowed'], 405);
}
public function getList(ServerRequestInterface $request, DelegateInterface $delegate)
public function getList(ServerRequestInterface $request) : ResponseInterface
{
return $this->createResponse(['content' => 'Method not allowed'], 405);
}
public function create(ServerRequestInterface $request, DelegateInterface $delegate)
public function create(ServerRequestInterface $request) : ResponseInterface
{
return $this->createResponse(['content' => 'Method not allowed'], 405);
}
public function update(ServerRequestInterface $request, DelegateInterface $delegate)
public function update(ServerRequestInterface $request) : ResponseInterface
{
return $this->createResponse(['content' => 'Method not allowed'], 405);
}
public function delete(ServerRequestInterface $request, DelegateInterface $delegate)
public function delete(ServerRequestInterface $request) : ResponseInterface
{
return $this->createResponse(['content' => 'Method not allowed'], 405);
}
public function deleteList(ServerRequestInterface $request, DelegateInterface $delegate)
public function deleteList(ServerRequestInterface $request) : ResponseInterface
{
return $this->createResponse(['content' => 'Method not allowed'], 405);
}
public function head(ServerRequestInterface $request, DelegateInterface $delegate)
public function head(ServerRequestInterface $request) : ResponseInterface
{
return $this->createResponse(['content' => 'Method not allowed'], 405);
}
public function options(ServerRequestInterface $request, DelegateInterface $delegate)
public function options(ServerRequestInterface $request) : ResponseInterface
{
return $this->createResponse(['content' => 'Method not allowed'], 405);
}
public function patch(ServerRequestInterface $request, DelegateInterface $delegate)
public function patch(ServerRequestInterface $request) : ResponseInterface
{
return $this->createResponse(['content' => 'Method not allowed'], 405);
}
final protected function createResponse($data, $status = 200)
final protected function createResponse($data, $status = 200) : ResponseInterface
{
return new JsonResponse($data, $status);
}

View File

@@ -1,12 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Action;
use App\Service\SkiesClientService;
use Interop\Http\ServerMiddleware\DelegateInterface;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\JsonResponse;
use Zend\Diactoros\Response\TextResponse;
class ActivityAction extends AbstractAction
{
@@ -20,13 +22,23 @@ class ActivityAction extends AbstractAction
$this->skiesClient = $skiesClient;
}
public function getList(ServerRequestInterface $request, DelegateInterface $delegate)
/**
* @param ServerRequestInterface $request
* @return ResponseInterface
* @throws GuzzleException
*/
public function getList(ServerRequestInterface $request) : ResponseInterface
{
$authHeader = $request->getHeaderLine("x-passthru-auth");
return new JsonResponse($this->skiesClient->setAuthHeader($authHeader)->getActivities());
}
public function get(ServerRequestInterface $request, DelegateInterface $delegate)
/**
* @param ServerRequestInterface $request
* @return ResponseInterface
* @throws GuzzleException
*/
public function get(ServerRequestInterface $request) : ResponseInterface
{
$id = $request->getAttribute(self::IDENTIFIER_NAME);
$authHeader = $request->getHeaderLine("x-passthru-auth");

View File

@@ -3,12 +3,12 @@
namespace App\Action;
use App\Service\SkiesClientService;
use Interop\Http\ServerMiddleware\DelegateInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response\JsonResponse;
class ActivitySignoffAction implements ServerMiddlewareInterface
class ActivitySignoffAction implements RequestHandlerInterface
{
/**
* @var SkiesClientService
@@ -20,7 +20,12 @@ class ActivitySignoffAction implements ServerMiddlewareInterface
$this->skiesClient = $skiesClient;
}
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
/**
* @param ServerRequestInterface $request
* @return ResponseInterface
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$authHeader = $request->getHeaderLine("x-passthru-auth");
$id = $request->getAttribute("id");

View File

@@ -3,12 +3,12 @@
namespace App\Action;
use App\Service\SkiesClientService;
use Interop\Http\ServerMiddleware\DelegateInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response\JsonResponse;
class ActivitySignupAction implements ServerMiddlewareInterface
class ActivitySignupAction implements RequestHandlerInterface
{
/**
* @var SkiesClientService
@@ -20,7 +20,12 @@ class ActivitySignupAction implements ServerMiddlewareInterface
$this->skiesClient = $skiesClient;
}
public function process(ServerRequestInterface $request, DelegateInterface $delegate)
/**
* @param ServerRequestInterface $request
* @return ResponseInterface
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function handle(ServerRequestInterface $request) : ResponseInterface
{
$authHeader = $request->getHeaderLine("x-passthru-auth");
$id = $request->getAttribute("id");

View File

@@ -6,12 +6,21 @@ use App\Entity\Activity;
use App\Entity\Comment;
use App\Entity\User;
use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJarInterface;
use GuzzleHttp\Cookie\FileCookieJar;
use function GuzzleHttp\Psr7\parse_query;
use Psr\Http\Message\ResponseInterface;
use Ramsey\Uuid\Uuid;
use Zend\Diactoros\Uri;
use Zend\Dom\Document;
use Zend\Expressive\Exception\MissingDependencyException;
class SkiesClientService
{
const APP_REALM = '7302c625-70ba-e311-80c0-00155da22c45';
const ADFS_AUTH_URL = "https://fs.sigmatechnology.se/adfs/ls";
const SKIES_BASE_URL = 'https://skies.sigmatechnology.se/';
const SKIES_MAIN_URL = "https://skies.sigmatechnology.se/main.asp";
const SKIES_PROFILE_URL = "https://skies.sigmatechnology.se/main.asp?rID=1&alt=2&username=%s";
const SKIES_ACTIVITIES_URL = "https://skies.sigmatechnology.se/main.asp?rID=2";
@@ -19,31 +28,81 @@ class SkiesClientService
const SKIES_ACTIVITY_SIGNUP_URL = "https://skies.sigmatechnology.se/main.asp?rID=2&alt=1&aktID=%s&doJoin=1";
const SKIES_ACTIVITY_SIGNOFF_URL = "https://skies.sigmatechnology.se/main.asp?rID=2&alt=1&aktID=%s&doCancel=1&user=%s";
/**
* @var Client
*/
/** @var Client */
private $client;
/**
* @var string
*/
private $authHeader = null;
/** @var string */
private $authUser = null;
/** @var string */
private $authPass = null;
/** @var CookieJarInterface */
private $cookieJar = null;
private $counter = 0;
/**
* SkiesClientService constructor.
* @param Client $client
*/
public function __construct(Client $client)
{
$this->client = $client;
}
/**
* @throws \Exception
*/
private function getAuthCookies()
{
if ($this->authUser == null) {
throw new MissingDependencyException("X-Passthru-Auth header is missing");
}
// try to fetch the main page, only renew auth cookie if we can't
$testRequest = $this->client->get(self::SKIES_MAIN_URL, [
'cookies' => $this->cookieJar,
'allow_redirects' => false,
]);
if (200 == $testRequest->getStatusCode()) {
return;
}
$this->client->post(self::ADFS_AUTH_URL, [
'cookies' => $this->cookieJar,
'allow_redirects' => true,
'query' => [
'version' => '1.0',
'action' => 'signin',
'realm' => 'urn:AppProxy:com',
'appRealm' => self::APP_REALM,
'returnUrl' => self::SKIES_BASE_URL,
'client-request-id' => Uuid::uuid1(),
],
'form_params' => [
'UserName' => $this->authUser,
'Password' => $this->authPass,
'AuthMethod' => 'FormsAuthentication',
]
]);
}
/**
* @param string $authHeader
* @return SkiesClientService
*/
public function setAuthHeader(string $authHeader): SkiesClientService
{
$this->authHeader = $authHeader;
list($this->authUser, $this->authPass) = explode(':', base64_decode($authHeader));
$this->cookieJar = new FileCookieJar("data/cache/".$this->authUser, true);
return $this;
}
/**
* @return bool
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getNews()
{
$response = $this->doSkiesRequest('GET', self::SKIES_MAIN_URL);
@@ -53,6 +112,7 @@ class SkiesClientService
/**
* @return Activity[]
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getActivities()
{
@@ -64,6 +124,7 @@ class SkiesClientService
/**
* @param string $htmlBody
* @return Activity[]
* @throws \GuzzleHttp\Exception\GuzzleException
*/
private function parseActivitiesPage(string $htmlBody)
{
@@ -97,6 +158,7 @@ class SkiesClientService
/**
* @param int $id
* @return Activity
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getActivity(int $id): Activity
{
@@ -108,6 +170,7 @@ class SkiesClientService
/**
* @param int $id
* @return Activity
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function signUpActivity(int $id): Activity
{
@@ -122,6 +185,7 @@ class SkiesClientService
/**
* @param int $id
* @return Activity
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function signOffActivity(int $id): Activity
{
@@ -134,6 +198,7 @@ class SkiesClientService
* @param string $htmlBody
* @param int $id
* @return Activity
* @throws \GuzzleHttp\Exception\GuzzleException
*/
private function parseActivityPage(string $htmlBody, int $id): Activity
{
@@ -333,6 +398,11 @@ class SkiesClientService
return false;
}
/**
* @param string $username
* @return string
* @throws \GuzzleHttp\Exception\GuzzleException
*/
private function getDisplayName(string $username): string
{
$response = $this->doSkiesRequest("GET", sprintf(self::SKIES_PROFILE_URL, $username));
@@ -368,18 +438,19 @@ class SkiesClientService
* @param string $url
* @param array $options
* @return ResponseInterface
* @throws \GuzzleHttp\Exception\GuzzleException
* @throws \Exception
*/
private function doSkiesRequest(string $method, string $url, $options = []): ResponseInterface
{
if ($this->authHeader == null) {
throw new MissingDependencyException("X-Passthru-Auth header is missing");
}
return $this->client
$this->getAuthCookies();
$this->counter += 1;
$response = $this->client
->request($method, $url, [
'headers' => [
'Authorization' => "Basic {$this->authHeader}",
]
'cookies' => $this->cookieJar,
'allow_redirects' => true,
] + $options);
return $response;
}
/**
@@ -387,11 +458,7 @@ class SkiesClientService
*/
private function getUsername(): string
{
if (null == $this->authHeader) {
throw new MissingDependencyException("X-Passthru-Auth header is missing");
}
$decodedHeader = base64_decode($this->authHeader);
list($username) = explode(":", $decodedHeader);
return $username;
list(,$signum) = explode("\\", $this->authUser);
return $signum;
}
}

View File

@@ -10,7 +10,7 @@ class SkiesClientServiceFactory
public function __invoke(ContainerInterface $container)
{
$httpClient = new Client([
'cookies' => true,
'allow_redirects' => true,
]);
return new SkiesClientService($httpClient);
}