Skip to content

Commit

Permalink
symfony security
Browse files Browse the repository at this point in the history
  • Loading branch information
sveneld committed Nov 12, 2024
1 parent 4899dc6 commit b2df5bd
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 70 deletions.
32 changes: 0 additions & 32 deletions actions-web.php
Original file line number Diff line number Diff line change
Expand Up @@ -516,38 +516,6 @@ function changecity($userid, $city)
}


function resetpassword($number)
{
global $db, $mailer;

$number = $db->escape(trim($number));

$result = $db->query("SELECT mail,userName FROM users WHERE number='$number'");
if (!$result->num_rows) {
response(_('No such user found.'), 1);
}

$row = $result->fetch_assoc();
$email = $row['mail'];
$username = $row['userName'];

$subject = _('Password reset');

mt_srand(crc32(microtime()));
$password = substr(md5(mt_rand() . microtime() . $email), 0, 8);

$result = $db->query("UPDATE users SET password=SHA2('$password',512) WHERE number='" . $number . "'");

$names = preg_split("/[\s,]+/", $username);
$firstname = $names[0];
$message = _('Hello') . ' ' . $firstname . ",\n\n" .
_('Your password has been reset successfully.') . "\n\n" .
_('Your new password is:') . "\n" . $password;

$mailer->sendMail($email, $subject, $message);
response(_('Your password has been reset successfully.') . ' ' . _('Check your email.'));
}

function mapgetmarkers($userId)
{
global $db, $configuration, $user;
Expand Down
3 changes: 0 additions & 3 deletions command.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@
$existing=trim($_GET["existing"]);
register($number,$smscode,$checkcode,$fullname,$useremail,$password,$password2,$existing);
break;
case "resetpassword":
resetpassword($_GET["number"]);
break;
case "list":
$stand=trim($_GET["stand"]);
listbikes($stand);
Expand Down
4 changes: 4 additions & 0 deletions config/packages/security.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
->accessControl()
->path('^/agree.php$')
->roles(['IS_AUTHENTICATED_ANONYMOUSLY']);
$security
->accessControl()
->path('^/resetPassword$')
->roles(['IS_AUTHENTICATED_ANONYMOUSLY']);

$security
->accessControl()
Expand Down
3 changes: 2 additions & 1 deletion config/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@
->controller([\BikeShare\Controller\SecurityController::class, 'login']);
$routes->add('logout', '/logout')
->controller([\BikeShare\Controller\SecurityController::class, 'logout']);

$routes->add('reset_password', '/resetPassword')
->controller([\BikeShare\Controller\SecurityController::class, 'resetPassword']);
};
22 changes: 0 additions & 22 deletions public/js/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,13 @@ $(document).ready(function () {
$('.bicycleactions').hide();
$('#notetext').hide();
$('#couponblock').hide();
$('#passwordresetblock').hide();
$("#rent").hide();
$(document).ajaxStart(function () {
$('#overlay').show();
});
$(document).ajaxStop(function () {
$('#overlay').hide();
});
$("#password").focus(function () {
$('#passwordresetblock').show();
});
$("#resetpassword").click(function () {
if (window.ga) ga('send', 'event', 'buttons', 'click', 'password-reset');
resetpassword();
});
$("#rent").click(function () {
if (window.ga) ga('send', 'event', 'buttons', 'click', 'bike-rent');
rent();
Expand Down Expand Up @@ -504,20 +496,6 @@ function validatecoupon() {
});
}

function resetpassword() {
$('#passwordresetblock').hide();
if (sms == 0 && $('#number').val() > 0) {
$.ajax({
url: "command.php?action=resetpassword&number=" + $('#number').val()
}).done(function (jsonresponse) {
jsonobject = $.parseJSON(jsonresponse);
handleresponse(jsonobject);
});
} else if (sms == 1 && $('#number').val() > 0) {
window.location = "register.php#reset" + $('#number').val();
}
}

function attachbicycleinfo(element, attachto) {
$('#' + attachto + ' .bikenumber').html($(element).attr('data-id'));
// show warning, if exists:
Expand Down
7 changes: 7 additions & 0 deletions src/App/Entity/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
public function __construct(
int $userId,
string $number,
string $email,
string $password,
string $city,
string $userName,
int $privileges
) {
$this->userId = $userId;
$this->number = $number;
$this->email = $email;
$this->password = $password;
$this->city = $city;
$this->userName = $userName;
Expand All @@ -42,6 +44,11 @@ public function getNumber(): string
return $this->number;
}

public function getEmail(): string
{
return $this->email;
}

public function getPrivileges(): int
{
return $this->privileges;
Expand Down
19 changes: 15 additions & 4 deletions src/App/Security/UserProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function loadUserByIdentifier(string $identifier): UserInterface
{
$identifier = $this->phonePurifier->purify($identifier);
$result = $this->db->query(
"SELECT userId, number, password, city, userName, privileges FROM users WHERE number='$identifier'"
"SELECT userId, number, mail, password, city, userName, privileges FROM users WHERE number='$identifier'"
);
if (!$result || $result->rowCount() == 0) {
throw new UserNotFoundException(sprintf('Unknown user %s', $identifier));
Expand All @@ -58,6 +58,7 @@ public function loadUserByIdentifier(string $identifier): UserInterface
return new User(
(int)$row['userId'],
$row['number'],
$row['mail'],
$row['password'],
$row['city'],
$row['userName'],
Expand Down Expand Up @@ -102,8 +103,18 @@ public function supportsClass(string $class): bool
*/
public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void
{
// TODO: when hashed passwords are in use, this method should:
// 1. persist the new password in the user storage
// 2. update the $user object with $user->setPassword($newHashedPassword);
$this->db->query(
"UPDATE users SET password='$newHashedPassword' WHERE number='" . $user->getNumber() . "'"
);

$user = new User(
$user->getUserId(),
$user->getNumber(),
$user->getEmail(),
$newHashedPassword,
$user->getCity(),
$user->getUsername(),
$user->getPrivileges()
);
}
}
63 changes: 63 additions & 0 deletions src/Controller/SecurityController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@
namespace BikeShare\Controller;

use BikeShare\App\Configuration;
use BikeShare\Mail\MailSenderInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\Translation\TranslatorInterface;

class SecurityController extends AbstractController
{
Expand Down Expand Up @@ -39,4 +45,61 @@ public function logout()
// controller can be blank: it will never be executed!
throw new \Exception('Don\'t forget to activate logout in security.php');
}

/**
* @Route("/resetPassword", name="reset_password")
*/
public function resetPassword(
Request $request,
Configuration $configuration,
MailSenderInterface $mailer,
UserProviderInterface $userProvider,
UserPasswordHasherInterface $passwordHasher,
TranslatorInterface $translator
) {
if ($request->isMethod('POST')) {
$number = $request->request->get('_username');

try {
$user = $userProvider->loadUserByIdentifier($number);
} catch (UserNotFoundException $e) {
$user = null;
}

if (!is_null($user)) {
mt_srand(crc32(microtime()));
$plainPassword = substr(md5(mt_rand() . microtime() . $user->getUsername()), 0, 8);
$hashedPassword = $passwordHasher->hashPassword(
$user,
$plainPassword
);
$userProvider->upgradePassword($user, $hashedPassword);

$subject = $translator->trans('Password reset');
$names = preg_split("/[\s,]+/", $user->getUsername());
$firstname = $names[0];
$message = $translator->trans('Hello') . ' ' . $firstname . ",\n\n" .
$translator->trans('Your password has been reset successfully.') . "\n\n" .
$translator->trans('Your new password is:') . "\n" . $plainPassword;

$mailer->sendMail($user->getEmail(), $subject, $message);
}

$this->addFlash(
'success',
$translator->trans('Your password has been reset successfully.')
. ' '
. $translator->trans('Check your email.')
);

return $this->redirectToRoute('reset_password');
}

return $this->render(
'security/reset_password.html.twig',
[
'isSmsSystemEnabled' => $configuration->get('connectors')['sms'] == '',
]
);
}
}
5 changes: 1 addition & 4 deletions templates/base.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">
<a class="navbar-brand" href="/">
<img src="{{ asset('images/logo_small.svg') }}" width="30" height="30" class="d-inline-block align-top" alt="Logo">
{{ siteName }}
</a>
Expand All @@ -19,9 +19,6 @@
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="https://whitebikes.info/">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://wiki.whitebikes.info/index.php/Ako_to_funguje%3F">{{ 'How it works'|trans }}</a>
</li>
Expand Down
3 changes: 3 additions & 0 deletions templates/security/login.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
<div class="form-group">
<label for="password">
{{ 'Password:'|trans }}
<small>
(<a href="{{ path('reset_password') }}">{{ 'Forgotten? Reset password'|trans }}</a>)
</small>
</label>
<input type="password" id="password" name="_password" class="form-control" required>
</div>
Expand Down
25 changes: 25 additions & 0 deletions templates/security/reset_password.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{% extends 'base.html.twig' %}

{% block body %}
<div class="container mt-5">

{% for message in app.flashes('success') %}
<div class="alert alert-success">
{{ message }}
</div>
{% endfor %}

<form action="{{ path('reset_password') }}" method="post" class="form-signin">
<div class="form-group">
<label for="username">
{% if isSmsSystemEnabled %}{{ 'Phone number:'|trans }}{% else %}{{ 'User number:'|trans }}{% endif %}
</label>
<input type="text" id="username" name="_username" value="" class="form-control" required autofocus>
</div>

<button type="submit" class="btn btn-primary btn-block">
{{ 'Forgotten? Reset password'|trans }}
</button>
</form>
</div>
{% endblock %}
8 changes: 4 additions & 4 deletions translations/messages+intl-icu.en.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,10 @@
'Invalid coupon, try again.' => '',
'No such user found.' => '',
'Password reset' => 'Password reset',
'Hello' => '',
'Your password has been reset successfully.' => '',
'Your new password is:' => '',
'Check your email.' => '',
'Hello' => 'Hello',
'Your password has been reset successfully.' => 'Your password has been reset successfully.',
'Your new password is:' => 'Your new password is:',
'Check your email.' => 'Check your email.',
'registration' => '',
'Registration' => '',
'Step 1 - Confirm your phone number' => '',
Expand Down

0 comments on commit b2df5bd

Please sign in to comment.