Skip to content

Commit

Permalink
symfony security
Browse files Browse the repository at this point in the history
  • Loading branch information
sveneld committed Nov 10, 2024
1 parent 5225021 commit 4899dc6
Show file tree
Hide file tree
Showing 20 changed files with 539 additions and 608 deletions.
2 changes: 1 addition & 1 deletion admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
<li><a href="<?= $configuration->get('systemURL'); ?>"><?= _('Map'); ?></a></li>
<li class="active"><a href="<?= $configuration->get('systemURL'); ?>admin.php"><?= _('Admin'); ?></a></li>
<?php if ($auth->isLoggedIn()): ?>
<li><a href="command.php?action=logout" id="logout"><?= _('Log out'); ?></a></li>
<li><a href="/logout" id="logout"><?= _('Log out'); ?></a></li>
<?php endif; ?>
</ul>
</div><!--/.nav-collapse -->
Expand Down
10 changes: 0 additions & 10 deletions command.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
require_once 'actions-web.php';

$userid = $auth->getUserId();
$session = $auth->getSessionId();

/**
* @var RentSystemInterface $rentSystem
Expand All @@ -33,15 +32,6 @@
$existing=trim($_GET["existing"]);
register($number,$smscode,$checkcode,$fullname,$useremail,$password,$password2,$existing);
break;
case "login":
$number=trim($_POST["number"]);
$number = $phonePurifier->purify($number);
$password=trim($_POST["password"]);
$auth->login($number,$password);
break;
case "logout":
$auth->logout();
break;
case "resetpassword":
resetpassword($_GET["number"]);
break;
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
"symfony/twig-bundle": "^5.4",
"symfony/dotenv": "^5.4",
"symfony/translation": "^5.4",
"symfony/asset": "^5.4"
"symfony/asset": "^5.4",
"symfony/security-bundle": "^5.4"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.10|^4.0",
Expand Down
5 changes: 3 additions & 2 deletions config/bundles.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
declare(strict_types=1);

return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
\Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
\Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
\Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
\Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
];
9 changes: 7 additions & 2 deletions config/packages/framework.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@

declare(strict_types=1);

use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Config\FrameworkConfig;

return static function (FrameworkConfig $framework): void {
$framework->phpErrors()
->throw(false);

$framework->session()
->storageFactoryId('session.storage.factory.php_bridge')
->handlerId(null);
->enabled(true)
->handlerId(null)
->cookieSecure('auto')
->cookieSamesite(Cookie::SAMESITE_LAX)
->storageFactoryId('session.storage.factory.native')
;

$framework->secret('%env(APP_SECRET)%');

Expand Down
67 changes: 67 additions & 0 deletions config/packages/security.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

use BikeShare\App\Security\TokenProvider;
use BikeShare\App\Security\UserProvider;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Config\SecurityConfig;

return function (SecurityConfig $security) {
$security
->passwordHasher(PasswordAuthenticatedUserInterface::class)
->algorithm('sha512')
->encodeAsBase64(false)
->iterations(1);

$security
->provider('app_user_provider')
->id(UserProvider::class);

$security
->firewall('dev')
->pattern('^/(_(profiler|wdt)|css|images|js)/')
->security(false);

$mainFirewall = $security->firewall('main');
$mainFirewall->anonymous();
$mainFirewall
->formLogin()
->loginPath('login')
->checkPath('login');
$mainFirewall
->logout()
->path('logout')
->target('/');
$mainFirewall
->rememberMe()
->secret('%kernel.secret%')
->lifetime(604800) // 1 week in seconds
->tokenProvider(
[
'service' => TokenProvider::class,
]
);

$security
->accessControl()
->path('^/login$')
->roles(['IS_AUTHENTICATED_ANONYMOUSLY']);
$security
->accessControl()
->path('^/(sms/)?receive.php$')
->roles(['IS_AUTHENTICATED_ANONYMOUSLY']);
$security
->accessControl()
->path('^/register.php$')
->roles(['IS_AUTHENTICATED_ANONYMOUSLY']);
$security
->accessControl()
->path('^/agree.php$')
->roles(['IS_AUTHENTICATED_ANONYMOUSLY']);

$security
->accessControl()
->path('^/')
->roles(['ROLE_USER']);
};
5 changes: 5 additions & 0 deletions config/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@
->controller([\BikeShare\Controller\SmsRequestController::class, 'index']);
$routes->add('agree', '/agree.php')
->controller([\BikeShare\Controller\AgreeController::class, 'index']);
$routes->add('login', '/login')
->controller([\BikeShare\Controller\SecurityController::class, 'login']);
$routes->add('logout', '/logout')
->controller([\BikeShare\Controller\SecurityController::class, 'logout']);

};
1 change: 1 addition & 0 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
'../src/SmsConnector/SmsGateway/SmsGateway.php',
'../src/App/Configuration.php',
'../src/App/Kernel.php',
'../src/App/Entity',
]);

$services->get(MysqliDb::class)
Expand Down
2 changes: 1 addition & 1 deletion index.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
echo '</select></li>';
}

echo '<li><a href="command.php?action=logout" id="logout"><span class="glyphicon glyphicon-log-out"></span> ', _('Log out'), '</a></li>';
echo '<li><a href="/logout" id="logout"><span class="glyphicon glyphicon-log-out"></span> ', _('Log out'), '</a></li>';
}
?>
</ul>
Expand Down
7 changes: 7 additions & 0 deletions public/images/logo_small.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion scan.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

$auth->refreshSession();
$userid = $auth->getUserId();
$session = $auth->getSessionId();

if (!$auth->isLoggedIn()) {
response("<h3>" . _('You are not logged in.') . "</h3>", ERROR);
Expand Down
84 changes: 84 additions & 0 deletions src/App/Entity/User.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

declare(strict_types=1);

namespace BikeShare\App\Entity;

use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class User implements UserInterface, PasswordAuthenticatedUserInterface
{
private int $userId;
private string $number;
private string $password;
private string $city;
private string $userName;
private int $privileges;

public function __construct(
int $userId,
string $number,
string $password,
string $city,
string $userName,
int $privileges
) {
$this->userId = $userId;
$this->number = $number;
$this->password = $password;
$this->city = $city;
$this->userName = $userName;
$this->privileges = $privileges;
}

public function getCity(): string
{
return $this->city;
}

public function getNumber(): string
{
return $this->number;
}

public function getPrivileges(): int
{
return $this->privileges;
}

public function getUserId(): int
{
return $this->userId;
}

public function getUsername(): string
{
return $this->userName;
}

public function getPassword(): string
{
return $this->password;
}

public function getUserIdentifier(): string
{
return $this->number;
}

public function getRoles(): array
{
return ['ROLE_USER'];
}

public function getSalt(): ?string
{
return null;
}

public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
}
}
94 changes: 94 additions & 0 deletions src/App/Security/TokenProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

namespace BikeShare\App\Security;

use BikeShare\Db\DbInterface;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentTokenInterface;
use Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface;
use Symfony\Component\Security\Core\Exception\TokenNotFoundException;

class TokenProvider implements TokenProviderInterface
{
private $tokens = [];
private DbInterface $db;

public function __construct(
DbInterface $db
) {
$this->db = $db;
}

public function loadTokenBySeries(string $series)
{
if (!isset($this->tokens[$series])) {
$result = $this->db->query(
"SELECT * FROM remember_me_tokens WHERE series='$series'"
);
if (!$result || $result->rowCount() == 0) {
throw new TokenNotFoundException('No token found.');
}

$row = $result->fetchAssoc();

$this->tokens[$series] = new PersistentToken(
$row['class'],
$row['username'],
$row['series'],
$row['value'],
new \DateTime($row['lastUsed'])
);
}

return $this->tokens[$series];
}

/**
* {@inheritdoc}
*/
public function updateToken(string $series, string $tokenValue, \DateTime $lastUsed)
{
$currentToken = $this->loadTokenBySeries($series);

$token = new PersistentToken(
$currentToken->getClass(),
method_exists($currentToken, 'getUserIdentifier') ?
$currentToken->getUserIdentifier() : $currentToken->getUsername(),
$series,
$tokenValue,
$lastUsed
);
$this->tokens[$series] = $token;
}

/**
* {@inheritdoc}
*/
public function deleteTokenBySeries(string $series)
{
$this->db->query(
"DELETE FROM remember_me_tokens WHERE series='$series'"
);

unset($this->tokens[$series]);
}

/**
* {@inheritdoc}
*/
public function createNewToken(PersistentTokenInterface $token)
{
$this->db->query(
"INSERT INTO remember_me_tokens (class, username, series, value, lastUsed)
VALUES ('{$token->getClass()}',
'{$token->getUsername()}',
'{$token->getSeries()}',
'{$token->getTokenValue()}',
'{$token->getLastUsed()->format('Y-m-d H:i:s')}')"
);

$this->tokens[$token->getSeries()] = $token;
}
}
Loading

0 comments on commit 4899dc6

Please sign in to comment.