parent
7d75c50869
commit
85e202506a
@ -0,0 +1,104 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* Authserver, an OAuth2-based single-signon authentication provider written in PHP. |
||||||
|
* |
||||||
|
* Copyright (C) 2017 Lars Vierbergen |
||||||
|
* |
||||||
|
* his program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
namespace vierbergenlars\AuthserverStatsBundle\Entity; |
||||||
|
|
||||||
|
use Doctrine\ORM\Mapping as ORM; |
||||||
|
|
||||||
|
/** |
||||||
|
* @ORM\Entity |
||||||
|
* @ORM\Table(name="vierbergenlars_stats_auth") |
||||||
|
*/ |
||||||
|
class AuthenticationEntry |
||||||
|
{ |
||||||
|
|
||||||
|
/** |
||||||
|
* @ORM\Column(type="integer") |
||||||
|
* @ORM\Id |
||||||
|
* @ORM\GeneratedValue(strategy="AUTO") |
||||||
|
* |
||||||
|
* @var integer |
||||||
|
*/ |
||||||
|
private $id; |
||||||
|
|
||||||
|
/** |
||||||
|
* @ORM\Column(name="ip", type="string") |
||||||
|
* |
||||||
|
* @var string |
||||||
|
*/ |
||||||
|
private $ip; |
||||||
|
|
||||||
|
/** |
||||||
|
* @ORM\Column(name="ts", type="datetime") |
||||||
|
* |
||||||
|
* @var \DateTime |
||||||
|
*/ |
||||||
|
private $timeStamp; |
||||||
|
|
||||||
|
/** |
||||||
|
* @ORM\Column(name="success", type="boolean") |
||||||
|
* |
||||||
|
* @var boolean |
||||||
|
*/ |
||||||
|
private $success; |
||||||
|
|
||||||
|
public function __construct($ip, $success) |
||||||
|
{ |
||||||
|
$this->ip = $ip; |
||||||
|
$this->success = $success; |
||||||
|
$this->timeStamp = new \DateTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @return number |
||||||
|
*/ |
||||||
|
public function getId() |
||||||
|
{ |
||||||
|
return $this->id; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public function getIp() |
||||||
|
{ |
||||||
|
return $this->ip; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @return \DateTime |
||||||
|
*/ |
||||||
|
public function getTimeStamp() |
||||||
|
{ |
||||||
|
return $this->timeStamp; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @return boolean |
||||||
|
*/ |
||||||
|
public function isSuccess() |
||||||
|
{ |
||||||
|
return $this->success; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,119 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Authserver, an OAuth2-based single-signon authentication provider written in PHP. |
||||||
|
* |
||||||
|
* Copyright (C) 2017 Lars Vierbergen |
||||||
|
* |
||||||
|
* his program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
namespace vierbergenlars\AuthserverStatsBundle\EventListener; |
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
||||||
|
use vierbergenlars\AuthserverStatsBundle\Event\StatsEvent; |
||||||
|
use Symfony\Bridge\Doctrine\RegistryInterface; |
||||||
|
use Symfony\Component\Security\Core\AuthenticationEvents; |
||||||
|
use Symfony\Component\Security\Core\Event\AuthenticationEvent; |
||||||
|
use vierbergenlars\AuthserverStatsBundle\Entity\AuthenticationEntry; |
||||||
|
use Symfony\Component\HttpFoundation\RequestStack; |
||||||
|
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent; |
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; |
||||||
|
|
||||||
|
class AuthenticationStatsListener implements EventSubscriberInterface |
||||||
|
{ |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @var RegistryInterface |
||||||
|
*/ |
||||||
|
private $registry; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @var RequestStack |
||||||
|
*/ |
||||||
|
private $requestStack; |
||||||
|
|
||||||
|
public static function getSubscribedEvents() |
||||||
|
{ |
||||||
|
return [ |
||||||
|
StatsEvent::class => [ |
||||||
|
[ |
||||||
|
'getAuthStats', |
||||||
|
-1 |
||||||
|
] |
||||||
|
], |
||||||
|
AuthenticationEvents::AUTHENTICATION_SUCCESS => [ |
||||||
|
'onAuthSuccess' |
||||||
|
], |
||||||
|
AuthenticationEvents::AUTHENTICATION_FAILURE => [ |
||||||
|
'onAuthFailure' |
||||||
|
] |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
public function __construct(RegistryInterface $registry, RequestStack $requestStack) |
||||||
|
{ |
||||||
|
$this->registry = $registry; |
||||||
|
$this->requestStack = $requestStack; |
||||||
|
} |
||||||
|
|
||||||
|
public function onAuthSuccess(AuthenticationEvent $event) |
||||||
|
{ |
||||||
|
if ($event->getAuthenticationToken() instanceof AnonymousToken) |
||||||
|
return; |
||||||
|
$authSuccess = new AuthenticationEntry($this->requestStack->getMasterRequest()->getClientIp(), true); |
||||||
|
$em = $this->registry->getManagerForClass(AuthenticationEntry::class); |
||||||
|
$em->persist($authSuccess); |
||||||
|
$em->flush($authSuccess); |
||||||
|
} |
||||||
|
|
||||||
|
public function onAuthFailure(AuthenticationFailureEvent $event) |
||||||
|
{ |
||||||
|
$authFailure = new AuthenticationEntry($this->requestStack->getMasterRequest()->getClientIp(), false); |
||||||
|
$em = $this->registry->getManagerForClass(AuthenticationEntry::class); |
||||||
|
$em->persist($authFailure); |
||||||
|
$em->flush($authFailure); |
||||||
|
} |
||||||
|
|
||||||
|
public function getAuthStats(StatsEvent $event) |
||||||
|
{ |
||||||
|
if (!$event->isEnabled('login')) |
||||||
|
return; |
||||||
|
|
||||||
|
$event->setMuninConfig('login', $event->getMuninConfig('login') + [ |
||||||
|
'auth_succ.label' => 'Authentication passes', |
||||||
|
'auth_succ.type' => 'COUNTER', |
||||||
|
'auth_fail.label' => 'Authentication failures', |
||||||
|
'auth_fail.type' => 'COUNTER' |
||||||
|
]); |
||||||
|
|
||||||
|
$queryBuilder = $this->registry->getRepository(AuthenticationEntry::class)->createQueryBuilder('e'); |
||||||
|
/* @var $queryBuilder \Doctrine\ORM\QueryBuilder */ |
||||||
|
$queryBuilder->select('count(e)', 'e.success')->groupBy('e.success'); |
||||||
|
$rawStats = $queryBuilder->getQuery()->getArrayResult(); |
||||||
|
$stats = [ |
||||||
|
'login.auth_succ' => 0, |
||||||
|
'login.auth_fail' => 0 |
||||||
|
]; |
||||||
|
foreach ($rawStats as $rawStat) { |
||||||
|
if ($rawStat['success']) { |
||||||
|
$stats['login.auth_succ'] += $rawStat['1']; |
||||||
|
} else { |
||||||
|
$stats['login.auth_fail'] += $rawStat['1']; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$event->addStatistics($stats); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
<?php |
||||||
|
/** |
||||||
|
* Authserver, an OAuth2-based single-signon authentication provider written in PHP. |
||||||
|
* |
||||||
|
* Copyright (C) $today.date Lars Vierbergen |
||||||
|
* |
||||||
|
* his program is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Affero General Public License as |
||||||
|
* published by the Free Software Foundation, either version 3 of the |
||||||
|
* License, or (at your option) any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Affero General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Affero General Public License |
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
namespace Application\Migrations; |
||||||
|
|
||||||
|
use Doctrine\DBAL\Migrations\AbstractMigration; |
||||||
|
use Doctrine\DBAL\Schema\Schema; |
||||||
|
|
||||||
|
class VersionAuthserverStats20171102211518 extends AbstractMigration |
||||||
|
{ |
||||||
|
|
||||||
|
public function up(Schema $schema) |
||||||
|
{ |
||||||
|
$authEntry = $schema->createTable('vierbergenlars_stats_auth'); |
||||||
|
|
||||||
|
$authEntry->addColumn('id', 'integer')->setAutoincrement(true); |
||||||
|
$authEntry->addColumn('ip', 'string'); |
||||||
|
$authEntry->addColumn('ts', 'datetime'); |
||||||
|
$authEntry->addColumn('success', 'boolean'); |
||||||
|
|
||||||
|
$authEntry->setPrimaryKey([ |
||||||
|
'id' |
||||||
|
]); |
||||||
|
} |
||||||
|
|
||||||
|
public function down(Schema $schema) |
||||||
|
{ |
||||||
|
$schema->dropTable('vierbergenlars_stats_auth'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
Reference in new issue