Skip to content

Commit

Permalink
Add recaptcha
Browse files Browse the repository at this point in the history
  • Loading branch information
florentpoujol committed Feb 8, 2018
1 parent cd17b33 commit cf1ccf1
Show file tree
Hide file tree
Showing 15 changed files with 144 additions and 67 deletions.
1 change: 1 addition & 0 deletions App/Controllers/Admin/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class Config extends AdminBaseController
"smtp_port" => "int",
"site_title" => "string",
"recaptcha_secret" => "string",
"recaptcha_site_key" => "string",
"use_nice_url" => "checkbox",
"allow_comments" => "checkbox",
"allow_registration" => "checkbox",
Expand Down
43 changes: 22 additions & 21 deletions App/Controllers/Login.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,43 +69,44 @@ public function postLogin()
"login_password" => "string"
]);

if ($this->validator->csrf("login")) {
if (!$this->validator->csrf("login")) {
$this->session->addError("csrffail");
} elseif (!$this->validator->recaptcha()) {
$this->session->addError("recaptchafail");
} else {
$formatOK = true;

if(! $this->validator->name($post["login_name"])) {
if (!$this->validator->name($post["login_name"])) {
$formatOK = false;
$this->session->addError("fieldvalidation.name");
}

if(! $this->validator->password($post["login_password"])) {
if (!$this->validator->password($post["login_password"])) {
$formatOK = false;
$this->session->addError("fieldvalidation.password");
}

if ($formatOK) {
$user = $this->userRepo->get(["name" => $post["login_name"]]);

if (is_object($user)) {
if ($user->email_token === "") {
if (password_verify($post["login_password"], $user->password_hash)) {
$this->session->set("minicms_modern_auth", $user->id);
$this->session->addSuccess("user.loggedin", ["username" => $user->name]);
$this->router->redirect("admin");
return;
} else {
$this->session->addError("user.wrongpassword");
}
} else {
$this->session->addError("user.notactivated");
$this->router->redirect("register/resendconfirmationemail");
return;
}
} else {
if (!is_object($user)) {
$this->session->addError("user.unknown");
}
elseif ($user->email_token !== "") {
$this->session->addError("user.notactivated");
$this->router->redirect("register/resendconfirmationemail");
return;
}
elseif (!password_verify($post["login_password"], $user->password_hash)) {
$this->session->addError("user.wrongpassword");
}
else {
$this->session->set("minicms_modern_auth", $user->id);
$this->session->addSuccess("user.loggedin", ["username" => $user->name]);
$this->router->redirect("admin");
return;
}
}
} else {
$this->session->addError("csrffail");
}

$this->render("login", ["post" => $post]);
Expand Down
76 changes: 42 additions & 34 deletions App/Controllers/Register.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,31 +71,35 @@ public function postRegister()
]);

if ($this->validator->csrf("register")) {
$user = [
"name" => $post["register_name"],
"email" => $post["register_email"],
"password" => $post["register_password"],
"password_confirmation" => $post["register_password_confirmation"],
];

if ($this->validator->user($user)) {
unset($post["password_confirm"]);
$user = $this->userRepo->create($user);

if (is_object($user)) {
$this->session->addSuccess("user.created");

if ($this->mailer->sendConfirmEmail($user)) {
$this->session->addSuccess("email.confirmemail");
$this->router->redirect("login");
return;
if ($this->validator->recaptcha()) {
$user = [
"name" => $post["register_name"],
"email" => $post["register_email"],
"password" => $post["register_password"],
"password_confirmation" => $post["register_password_confirmation"],
];

if ($this->validator->user($user)) {
unset($post["password_confirm"]);
$user = $this->userRepo->create($user);

if (is_object($user)) {
$this->session->addSuccess("user.created");

if ($this->mailer->sendConfirmEmail($user)) {
$this->session->addSuccess("email.confirmemail");
$this->router->redirect("login");
return;
} else {
$this->router->redirect("register/resendconfirmationemail");
return;
}
} else {
$this->router->redirect("register/resendconfirmationemail");
return;
$this->session->addError("db.createuser");
}
} else {
$this->session->addError("db.createuser");
}
} else {
$this->session->addError("recaptchafail");
}
} else {
$this->session->addError("csrffail");
Expand Down Expand Up @@ -148,26 +152,30 @@ public function postResendConfirmationEmail()
$post = $this->validator->sanitizePost(["confirm_email" => "string"]);

if ($this->validator->csrf("resendconfirmationemail")) {
if ($this->validator->email($post["confirm_email"])) {
$user = $this->userRepo->get(["email" => $post["confirm_email"]]);

if (is_object($user)) {
if ($user->email_token !== "") {
if ($this->mailer->sendConfirmEmail($user)) {
$this->session->addSuccess("email.confirmemail");
if ($this->validator->recaptcha()) {
if ($this->validator->email($post["confirm_email"])) {
$user = $this->userRepo->get(["email" => $post["confirm_email"]]);

if (is_object($user)) {
if ($user->email_token !== "") {
if ($this->mailer->sendConfirmEmail($user)) {
$this->session->addSuccess("email.confirmemail");
$this->router->redirect("login");
return;
}
} else {
$this->session->addError("user.alreadyactivated");
$this->router->redirect("login");
return;
}
} else {
$this->session->addError("user.alreadyactivated");
$this->router->redirect("login");
return;
$this->session->addError("user.unknown");
}
} else {
$this->session->addError("user.unknown");
$this->session->addError("fieldvalidation.email");
}
} else {
$this->session->addError("fieldvalidation.email");
$this->session->addError("recaptchafail");
}
} else {
$this->session->addError("csrffail");
Expand Down
21 changes: 18 additions & 3 deletions App/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ class Form
/**
* @var Session
*/
public $session;
protected $session;

/**
* @var Lang
*/
public $lang;
protected $lang;

/**
* @var Config
*/
protected $config;

/**
* @var string The name of the form, mostly used as prefix for CSRF protection
Expand All @@ -24,10 +29,11 @@ class Form
*/
private $data = [];

public function __construct(Session $session, Lang $lang)
public function __construct(Session $session, Lang $lang, Config $config)
{
$this->session = $session;
$this->lang = $lang;
$this->config = $config;
}

/**
Expand Down Expand Up @@ -351,6 +357,15 @@ public function textarea(string $name, $attributes = [])
echo $content;
}

public function recaptcha()
{
$siteKey = $this->config->get("recaptcha_site_key", "");
if ($siteKey !== "") {
echo '<div class="g-recaptcha" data-sitekey="' . $siteKey . '"></div>';
echo '<script src="https://www.google.com/recaptcha/api.js" async defer></script>';
}
}

public function br(int $count = 1)
{
while ($count--) {
Expand Down
3 changes: 2 additions & 1 deletion App/Renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ protected function getViewContent(string $template, string $view)
// process template functions
$functions = [
"queryString" => ["router", "getQueryString"],
"lang" => ["lang", "get"]
"lang" => ["lang", "get"],
"config" => ["config", "get"],
];

foreach ($functions as $name => $funcData) {
Expand Down
36 changes: 35 additions & 1 deletion App/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@ class Validator
*/
protected $database;

public function __construct(Session $session, Database $database)
/**
* @var Config
*/
protected $config;

public function __construct(Session $session, Database $database, Config $config)
{
$this->session = $session;
$this->database = $database;
$this->config = $config;
}

/**
Expand Down Expand Up @@ -356,4 +362,32 @@ public function media(array $data): bool

return $ok;
}

public function recaptcha(): bool
{
$secret = $this->config->get("recaptcha_secret", "");
if ($secret !== "") {
$postFields = [
"secret" => $secret,
"response" => $_POST["g-recaptcha-response"] ?? "no_response",
];
$postFields = http_build_query($postFields);

$url = "https://www.google.com/recaptcha/api/siteverify";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields); // gives me an array to string conversion error when not using http_build_query()
$response = curl_exec($curl);
curl_close($curl);

if (is_string($response)) {
$response = json_decode($response);
$response = $response->success;
}
return $response;
}
return true;
}
}
3 changes: 2 additions & 1 deletion App/views/admin/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
$form->checkbox("use_nice_url", false, "config.useniceurl");
$form->checkbox("allow_comments", false, "config.allowcomments");
$form->checkbox("allow_registration", false, "config.allowregistration");
$form->text("recaptcha_secret", "config.recaptcha");
$form->text("recaptcha_secret", "config.recaptcha_secret");
$form->text("recaptcha_site_key", "config.recaptcha_site_key");
$form->number("items_per_page", "config.iemsperpage");

?>
Expand Down
3 changes: 3 additions & 0 deletions App/views/login.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

{include messages.php}

<a href="{queryString register}">Register first !</a> <br> <br>

<?php
$form->setup("login", $post);

$form->open($router->getQueryString("login"));
$form->text("login_name", "Name:");
$form->password("login_password", "Password:");
$form->recaptcha();
$form->submit("", "Login");
$form->close();
?>
Expand Down
1 change: 1 addition & 0 deletions App/views/lostpassword.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
$form->setup("lostpassword", $post);
$form->open($router->getQueryString("login/lostpassword"));
$form->email("lostpassword_email", "Email: ");
$form->recaptcha();
$form->submit("", "Request password change");
$form->close();
?>
1 change: 1 addition & 0 deletions App/views/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
$form->email("register_email", "email");
$form->password("register_password", "password");
$form->password("register_password_confirmation", "password_confirmation");
$form->recaptcha();
$form->submit("", "Register");
$form->close();
?>
Expand Down
1 change: 1 addition & 0 deletions App/views/resendconfirmationemail.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
$form->setup("resendconfirmationemail", $post);
$form->open($router->getQueryString("register/resendconfirmationemail"));
$form->email("confirm_email", "email");
$form->recaptcha();
$form->submit("", "Resend email");
$form->close();
?>
1 change: 1 addition & 0 deletions App/views/resetpassword.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
$form->open($router->getQueryString("login/resetpassword"));
$form->text("resetpassword", "password");
$form->password("resetpassword_confirm", "password_confirm");
$form->recaptcha();
$form->submit("", "Reset Password");
$form->close();
?>
19 changes: 13 additions & 6 deletions App/views/templates/defaultAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,27 @@
<body>
<nav id="main-menu">
<ul>
@if ($user->isAdmin())
<li><a href="{queryString admin/config}">{lang config.title}</a></li>
@endif
<li><a href="{queryString blog}">{config site_title}</a></li>

@if ($user->isAdmin() || $user->isWriter())
<li><a href="{queryString admin/categories}">{lang category.title}</a></li>
<li><a href="{queryString admin/posts}">{lang post.title}</a></li>
<li><a href="{queryString admin/pages}">{lang page.title}</a></li>
<li><a href="{queryString admin/menus}">{lang menu.title}</a></li>
<li><a href="{queryString admin/medias}">{lang media.title}</a></li>
@endif

<li><a href="{queryString admin/comments}">{lang comment.title}</a></li>
<li><a href="{queryString admin/users}">{lang user.title}</a></li>

@if ($user->isAdmin() || $user->isWriter())
<li><a href="{queryString admin/menus}">{lang menu.title}</a></li>
<li><a href="{queryString admin/medias}">{lang media.title}</a></li>
@endif

@if ($user->isAdmin())
<li><a href="{queryString admin/config}">{lang config.title}</a></li>
@endif

<li><a href="{queryString logout}">{lang logout}</a></li>
<li><a href="{queryString blog}">{config site_title}</a></li>
</ul>
</nav>

Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"require": {
"php": "^7.0",
"ext-curl": "*",
"phpmailer/phpmailer": "^5.0.0",
"florentpoujol/php-standard-components": "0.0.2",
"michelf/php-markdown": "^1.0.0"
Expand Down
1 change: 1 addition & 0 deletions config/config.sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

"site_title": "My Site title",
"recaptcha_secret": "",
"recaptcha_site_key": "",
"use_nice_url": false,
"allow_comments": true,
"allow_registration": true,
Expand Down

0 comments on commit cf1ccf1

Please sign in to comment.