Skip to content

Commit

Permalink
added storage handlers, remove unused code, added listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
addeeandra committed Oct 10, 2024
1 parent 9ccdf66 commit 99445c8
Show file tree
Hide file tree
Showing 17 changed files with 247 additions and 66 deletions.
20 changes: 20 additions & 0 deletions src/Listeners/StoreSessionIP.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Dentro\Paranoia\Listeners;

use Dentro\Paranoia\Paranoia;
use Illuminate\Auth\Events\Login;

class StoreSessionIP
{
public function handle(Login $event): void
{
/** @var Paranoia $driver */
$driver = app('paranoia');
if ($driver->eligibleForIPRestriction()) {
$driver->saveSessionIpAddress();
}
}
}
20 changes: 20 additions & 0 deletions src/Listeners/StoreSessionUserAgent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Dentro\Paranoia\Listeners;

use Dentro\Paranoia\Paranoia;
use Illuminate\Auth\Events\Login;

class StoreSessionUserAgent
{
public function handle(Login $event): void
{
/** @var Paranoia $driver */
$driver = app('paranoia');
if ($driver->eligibleForUserAgentRestriction()) {
$driver->saveSessionUserAgent();
}
}
}
2 changes: 2 additions & 0 deletions src/Middlewares/FormViaHeaderMiddleware.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Dentro\Paranoia\Middlewares;

use Illuminate\Http\Request;
Expand Down
2 changes: 1 addition & 1 deletion src/Middlewares/GeoRestrictionMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function __construct(protected Paranoia $paranoia) {}
*/
public function handle(Request $request, \Closure $next): mixed
{
if (! $this->paranoia->shouldCheckGeoRestriction()) {
if (! $this->paranoia->eligibleForGeoRestriction()) {
return $next($request);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Middlewares/IPChangeRestrictionMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function __construct(protected Paranoia $paranoia) {}

public function handle(Request $request, \Closure $next): mixed
{
if (! $this->paranoia->shouldCheckIPRestriction()) {
if (! $this->paranoia->eligibleForIPRestriction()) {
return $next($request);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Middlewares/UserAgentChangeRestrictionMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function __construct(protected Paranoia $paranoia) {}

public function handle(Request $request, \Closure $next): mixed
{
if (! $this->paranoia->shouldCheckUserAgentRestriction()) {
if (! $this->paranoia->eligibleForUserAgentRestriction()) {
return $next($request);
}

Expand Down
42 changes: 27 additions & 15 deletions src/Paranoia.php
Original file line number Diff line number Diff line change
@@ -1,45 +1,57 @@
<?php

declare(strict_types=1);

namespace Dentro\Paranoia;

use Illuminate\Support\Facades\DB;
use Dentro\Paranoia\Storage\Contracts\SessionStorageContract;
use Dentro\Paranoia\Storage\SessionStorageHandler;

class Paranoia
{
protected function getSessionTable(): string
public function __construct(
protected SessionStorageContract $storage
) {}

public function eligibleForGeoRestriction(): bool
{
return auth()->guard()->check();
}

public function eligibleForIPRestriction(): bool
{
/** @var string */
return config('session.table', 'sessions');
return auth()->guard()->check();
}

public function shouldCheckGeoRestriction(): bool
public function eligibleForUserAgentRestriction(): bool
{
return auth()->guard()->check();
}

public function shouldCheckIPRestriction(): bool
public function isUsingBaseDriver(): bool
{
return $this->storage instanceof SessionStorageHandler;
}

public function saveSessionIpAddress(): void
{
return session()->getDefaultDriver() === 'database' && $this->getSessionTable() !== null && auth()->guard()->check();
$this->storage->saveSessionIpAddress(session()->id());
}

public function shouldCheckUserAgentRestriction(): bool
public function saveSessionUserAgent(): void
{
return session()->getDefaultDriver() === 'database' && $this->getSessionTable() !== null && auth()->guard()->check();
$this->storage->saveSessionUserAgent(session()->id());
}

public function getSessionIpAddress(): ?string
{
/** @var string|null */
return DB::table($this->getSessionTable())
->where('id', session()->getId())
->value('ip_address');
return $this->storage->getSavedIpAddress(session()->id());
}

public function getSessionUserAgent(): ?string
{
/** @var string|null */
return DB::table($this->getSessionTable())
->where('id', session()->getId())
->value('user_agent');
return $this->storage->getSavedUserAgent(session()->id());
}
}
16 changes: 15 additions & 1 deletion src/ParanoiaServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Dentro\Paranoia;

use Dentro\Paranoia\Providers\EventServiceProvider;
use Dentro\Paranoia\Storage\SessionStorageFactory;
use Illuminate\Support\ServiceProvider;

class ParanoiaServiceProvider extends ServiceProvider
Expand All @@ -13,7 +14,20 @@ public function register(): void
{
$this->app->register(EventServiceProvider::class);

$this->app->bind(Paranoia::class, fn (): \Dentro\Paranoia\Paranoia => new Paranoia);
$this->app->bind(Paranoia::class, function (): \Dentro\Paranoia\Paranoia {

/** @var string $sessionDriver */
$sessionDriver = config('session.driver');
$factory = (new SessionStorageFactory($sessionDriver));

if ($sessionDriver === 'database') {
/** @var string $tableName */
$tableName = config('session.table');
$factory->setSessionTableName($tableName);
}

return new Paranoia($factory->build());
});
$this->app->alias(Paranoia::class, 'paranoia');

$this->mergeConfigFrom(__DIR__.'/../config/paranoia.php', 'paranoia');
Expand Down
11 changes: 8 additions & 3 deletions src/Providers/EventServiceProvider.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
<?php

declare(strict_types=1);

namespace Dentro\Paranoia\Providers;

use Dentro\Paranoia\Events\GeoRestrictionViolationDetected;
use Dentro\Paranoia\Listeners\StoreSessionIP;
use Dentro\Paranoia\Listeners\StoreSessionUserAgent;
use Illuminate\Auth\Events\Login;
use Illuminate\Support\ServiceProvider;

class EventServiceProvider extends ServiceProvider
Expand All @@ -11,8 +15,9 @@ class EventServiceProvider extends ServiceProvider
* @var array<string, array<string>>
*/
protected array $listen = [
GeoRestrictionViolationDetected::class => [
//
Login::class => [
StoreSessionIP::class,
StoreSessionUserAgent::class,
],
];
}
36 changes: 0 additions & 36 deletions src/Securities/SessionSecurity.php

This file was deleted.

16 changes: 16 additions & 0 deletions src/Storage/Contracts/SessionStorageContract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Dentro\Paranoia\Storage\Contracts;

interface SessionStorageContract
{
public function saveSessionIpAddress(string $sessionId): void;

public function saveSessionUserAgent(string $sessionId): void;

public function getSavedIpAddress(string $sessionId): ?string;

public function getSavedUserAgent(string $sessionId): ?string;
}
51 changes: 51 additions & 0 deletions src/Storage/SessionStorageDatabaseHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Dentro\Paranoia\Storage;

use Illuminate\Support\Facades\DB;

class SessionStorageDatabaseHandler implements Contracts\SessionStorageContract
{
public function __construct(
protected string $sessionTableName
) {}

public function saveSessionIpAddress(string $sessionId): void
{
// already handled by laravel's session handler
}

public function saveSessionUserAgent(string $sessionId): void
{
// already handled by laravel's session handler
}

public function getSavedIpAddress(string $sessionId): ?string
{
/** @var string|null */
return DB::table($this->sessionTableName)
->where('id', $sessionId)
->value('ip_address');
}

public function getSavedUserAgent(string $sessionId): ?string
{
/** @var string|null */
return DB::table($this->sessionTableName)
->where('id', $sessionId)
->value('user_agent');
}

/**
* @throws \Throwable
*/
public static function make(?string $tableName): SessionStorageDatabaseHandler
{
throw_if($tableName === null || $tableName === '' || $tableName === '0', new \InvalidArgumentException('Session table name is required for database driver'));

/** @var string $tableName */
return new self($tableName);
}
}
30 changes: 30 additions & 0 deletions src/Storage/SessionStorageFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Dentro\Paranoia\Storage;

class SessionStorageFactory
{
protected string $sessionTableName = 'sessions';

public function __construct(protected string $driver) {}

/**
* @throws \Throwable
*/
public function build(): Contracts\SessionStorageContract
{
return match ($this->driver) {
'database' => SessionStorageDatabaseHandler::make($this->sessionTableName),
default => SessionStorageHandler::make(),
};
}

public function setSessionTableName(string $sessionTableName): static
{
$this->sessionTableName = $sessionTableName;

return $this;
}
}
47 changes: 47 additions & 0 deletions src/Storage/SessionStorageHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace Dentro\Paranoia\Storage;

use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class SessionStorageHandler implements Contracts\SessionStorageContract
{
public function saveSessionIpAddress(string $sessionId): void
{
session()->put('ip_address', request()->ip());
}

public function saveSessionUserAgent(string $sessionId): void
{
session()->put('user_agent', request()->ip());
}

/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getSavedIpAddress(string $sessionId): ?string
{
return session()->get('ip_address') ?? null;

Check failure on line 28 in src/Storage/SessionStorageHandler.php

View workflow job for this annotation

GitHub Actions / Tests P8.3 - ubuntu-latest

Method Dentro\Paranoia\Storage\SessionStorageHandler::getSavedIpAddress() should return string|null but returns mixed.
}

/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function getSavedUserAgent(string $sessionId): ?string
{
return session()->get('user_agent') ?? null;

Check failure on line 37 in src/Storage/SessionStorageHandler.php

View workflow job for this annotation

GitHub Actions / Tests P8.3 - ubuntu-latest

Method Dentro\Paranoia\Storage\SessionStorageHandler::getSavedUserAgent() should return string|null but returns mixed.
}

/**
* @throws \Throwable
*/
public static function make(): SessionStorageHandler
{
return new self;
}
}
Loading

0 comments on commit 99445c8

Please sign in to comment.