Skip to content

Commit

Permalink
Merge pull request #5 from panique/master
Browse files Browse the repository at this point in the history
Uptade from head fork
  • Loading branch information
slaveek committed Dec 20, 2015
2 parents 4ab9dfb + 4c99ce1 commit 124be87
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 36 deletions.
7 changes: 6 additions & 1 deletion .htaccess
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ RewriteRule ^(.*) public/$1 [L]
</IfModule>

<ifmodule mod_headers.c>
# if you want to prevent your site from being embedded into other sites via an iframe (sometimes used for scam), then
# simply uncomment these lines below. you need to have apache rewrite headers activated, usually via
# "a2enmod rewrite headers" on the command line
#Header set X-Frame-Options Deny
#Header always append X-Frame-Options SAMEORIGIN
<filesmatch "\\.(ico|jpe?g|png|gif|swf)$">
Header set Cache-Control "max-age=2592000, public"
</filesmatch>
Expand All @@ -44,4 +49,4 @@ RewriteRule ^(.*) public/$1 [L]
<filesmatch "\\.(js)$">
Header set Cache-Control "max-age=216000, private"
</filesmatch>
</ifmodule>
</ifmodule>
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ Chris
- [Quick Installation](#quick-installation)
- [Detailed Installation](#detailed-installation)
- [NGINX setup](#nginx-setup)
+ [Documentation](#documentation)
+ [Documentation](#documentation)
- [How to use the user roles](#user_roles)
- [How to use the CSRF feature](#csrf)
+ [Community-provided features & feature discussions](#community)
+ [Future of the project, announcing soft EOL](#future)
+ [Why is there no support forum anymore ?](#why-no-support-forum)
Expand Down Expand Up @@ -374,7 +376,7 @@ doing this for free in our free time :)
- TODO: Full documentation
- TODO: Basic examples on how to do things

#### The different user roles
#### How to use the different user roles <a name="user_roles"></a>

Currently there are two types of users: Normal users and admins. There are exactly the same, but...

Expand All @@ -393,7 +395,7 @@ There's also a very interesting [pull request adding user roles and user permiss
which is not integrated into the project as it's too advanced and complex. But, this might be exactly what you need,
feel free to try.

#### An introduction into the CSRF features
#### How to use the CSRF feature <a name="csrf"></a>

To prevent [CSRF attacks](https://en.wikipedia.org/wiki/Cross-site_request_forgery), HUGE does this in the most common
way, by using a security *token* when the user submits critical forms. This means: When PHP renders a form for the user,
Expand All @@ -405,6 +407,18 @@ This CSRF prevention feature is currently implemented on the login form process
and user name change form process (see *application/view/user/editUsername.php*), most other forms are not security-
critical and should stay as simple as possible.

So, to do this with a normal form, simply: At your form, before the submit button put:
`<input type="hidden" name="csrf_token" value="<?= Csrf::makeToken(); ?>" />`
Then, in the controller action validate the CSRF token submitted with the form by doing:
```
// check if csrf token is valid
if (!Csrf::isTokenValid()) {
LoginModel::logout();
Redirect::home();
exit();
}
```

A big thanks to OmarElGabry for implementing this!

#### Can a user be logged in from multiple devices ?
Expand Down
5 changes: 3 additions & 2 deletions application/controller/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ public function index()
*/
public function login()
{

// check if csrf token is valid
if (!Csrf::isTokenValid()) {
self::logout();
LoginModel::logout();
Redirect::home();
exit();
}

// perform the login method, put result (true or false) into $login_successful
Expand Down
20 changes: 13 additions & 7 deletions application/core/Csrf.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@
* <input type="hidden" name="csrf_token" value="<?= Csrf::makeToken(); ?>" />
*
* This validation needed in the controller action method to validate CSRF token submitted with the form:
*
* if (!Csrf::isTokenValid()) {
* Login::logout();
* }
* And that's all
* LoginModel::logout();
* Redirect::home();
* exit();
* }
*
* To get simpler code it might be better to put the logout, redirect, exit into an own (static) method.
*/
class Csrf {

Expand All @@ -26,9 +30,10 @@ class Csrf {
* @static static method
* @return string
*/
public static function makeToken() {

$max_time = 60 * 60 * 24; // token is valid for 1 day
public static function makeToken()
{
// token is valid for 1 day
$max_time = 60 * 60 * 24;
$stored_time = Session::get('csrf_token_time');
$csrf_token = Session::get('csrf_token');

Expand All @@ -47,7 +52,8 @@ public static function makeToken() {
* @static static method
* @return bool
*/
public static function isTokenValid(){
public static function isTokenValid()
{
$token = Request::post('csrf_token');
return $token === Session::get('csrf_token') && !empty($token);
}
Expand Down
60 changes: 39 additions & 21 deletions application/core/DatabaseFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,44 @@
*/
class DatabaseFactory
{
private static $factory;
private $database;
private static $factory;
private $database;

public static function getFactory()
{
if (!self::$factory) {
self::$factory = new DatabaseFactory();
}
return self::$factory;
}
public static function getFactory()
{
if (!self::$factory) {
self::$factory = new DatabaseFactory();
}
return self::$factory;
}

public function getConnection() {
if (!$this->database) {
$options = array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING);
$this->database = new PDO(
Config::get('DB_TYPE') . ':host=' . Config::get('DB_HOST') . ';dbname=' .
Config::get('DB_NAME') . ';port=' . Config::get('DB_PORT') . ';charset=' . Config::get('DB_CHARSET'),
Config::get('DB_USER'), Config::get('DB_PASS'), $options
);
}
return $this->database;
}
}
public function getConnection() {
if (!$this->database) {

/**
* Check DB connection in try/catch block. Also when PDO is not constructed properly,
* prevent to exposing database host, username and password in plain text as:
* PDO->__construct('mysql:host=127....', 'root', '12345678', Array)
* by throwing custom error message
*/
try {
$options = array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING);
$this->database = new PDO(
Config::get('DB_TYPE') . ':host=' . Config::get('DB_HOST') . ';dbname=' .
Config::get('DB_NAME') . ';port=' . Config::get('DB_PORT') . ';charset=' . Config::get('DB_CHARSET'),
Config::get('DB_USER'), Config::get('DB_PASS'), $options
);
} catch (PDOException $e) {

// Echo custom message. Echo error code gives you some info.
echo 'Database connection can not be estabilished. Please try again later.' . '<br>';
echo 'Error code: ' . $e->getCode();

// Stop application :(
// No connection, reached limit connections etc. so no point to keep it running
exit;
}
}
return $this->database;
}
}
8 changes: 6 additions & 2 deletions application/core/Text.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ class Text
{
private static $texts;

public static function get($key)
public static function get($key, $data=NULL)
{
// if not $key
if (!$key) {
return null;
}

if ($data) {
foreach ($data as $var => $value) {
${$var} = $value;
}
}
// load config file (this is only done once per application lifecycle)
if (!self::$texts) {
self::$texts = require('../application/config/texts.php');
Expand Down

0 comments on commit 124be87

Please sign in to comment.