Skip to content

Commit

Permalink
Merge pull request #2 from panique/develop
Browse files Browse the repository at this point in the history
Develop update from head fork
  • Loading branch information
slaveek committed Oct 25, 2015
2 parents 748d4e4 + 2c80453 commit 9ef38da
Show file tree
Hide file tree
Showing 15 changed files with 484 additions and 31 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ language: php
php:
- 5.5
- 5.6
# http://docs.travis-ci.com/user/languages/php/#PHP-nightly-builds
- '7.0'
- 7
- hhvm

# optional, define the environment, in this case useful to test stuff that only runs in development / production
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ For the newest (und unstable) version always check the develop branch.

## develop branch

- [panique] [#729] Fix, mail sending now returns true or false success status (https://github.com/panique/huge/issues/729)
- [OmarElGabry] [PR](https://github.com/panique/huge/pull/693) session id regeneration in certain situations
- [OmarElGabry] [PR](https://github.com/panique/huge/pull/693) encrypted cookies
- [OmarElGabry] [PR](https://github.com/panique/huge/pull/693) new encryption class
- [OmarElGabry] [PR](https://github.com/panique/huge/pull/693) anti-CSRF feature (used in login and username change forms)
- [josh-bridge] [PR](https://github.com/panique/huge/pull/689) logged-in user can now change password
- [justincdotme] [PR](https://github.com/panique/huge/pull/684) better code for brute-force blocking when logging in
- [panique] soft autoinstaller improvements
Expand Down
106 changes: 93 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ Some interesting Buzzwords in this context: [KISS](http://en.wikipedia.org/wiki/
[YAGNI](http://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it), [Feature Creep](https://en.wikipedia.org/wiki/Feature_creep),
[Minimum viable product](https://en.wikipedia.org/wiki/Minimum_viable_product).

#### Current releases

* stable [v3.1](https://github.com/panique/huge/releases/tag/v3.1),
* public beta branch: [master-branch](https://github.com/panique/huge)
* public in-development branch (please commit new code here): [develop](https://github.com/panique/huge/tree/develop)

#### Quick-Index

+ [Features](#features)
Expand All @@ -34,14 +40,15 @@ Some interesting Buzzwords in this context: [KISS](http://en.wikipedia.org/wiki/
+ [License](#license)
+ [Requirements](#requirements)
+ [Auto-Installation](#auto-installation)
- [Auto-Installation in Vagrant](#auto-installation-vagrant)
- [Auto-Installation in Vagrant](#auto-installation-vagrant) (also useful for 100% reproducible installation of HUGE)
- [Auto-Installation in Ubuntu 14.04 LTS server](#auto-installation-ubuntu)
+ [Installation (Ubuntu 14.04 LTS)](#installation)
- [Quick Installation](#quick-installation)
- [Detailed Installation](#detailed-installation)
- [NGINX setup](#nginx-setup)
+ [Documentation](#documentation)
+ [Community-provided features & feature discussions](#community)
+ [Potential features for the future (or your forks)](#future)
+ [Why is there no support forum anymore ?](#why-no-support-forum)
+ [Zero tolerance for idiots, trolls and vandals](#zero-tolerance)
+ [Contribute](#contribute)
Expand All @@ -50,7 +57,7 @@ Some interesting Buzzwords in this context: [KISS](http://en.wikipedia.org/wiki/

### The History of HUGE

Back in 2010/2011 there we no useful login solutions in the PHP world, at least not for non-experts. So I did the worst
Back in 2010/2011 there were no useful login solutions in the PHP world, at least not for non-experts. So I did the worst
mistake every young developer does: Trying to build something by myself without having any clue about security basics.
What made it even worse was: The web was (and is) full of totally broken tutorials about building user authentication
systems, even the biggest companies in the world did this completely wrong (we are talking about SONY, LinkedIn and
Expand All @@ -77,32 +84,38 @@ And why the name "HUGE" ? It's a nice combination to

### Features <a name="features"></a>
* built with the official PHP password hashing functions, fitting the most modern password hashing/salting web standards
* proper security features, like CSRF blocking (via form tokens), encryption of cookie contents etc.
* users can register, login, logout (with username, email, password)
* [planned: OAuth2 implementation for proper future-proof 3rd party auth]
* password-forget / reset
* remember-me (login via cookie)
* account verification via mail
* captcha
* failed-login-throttling
* user profiles
* account upgrade / downgrade
* simple user types (type 1, type 2, admin)
* supports local avatars and remote Gravatars
* supports native mail and SMTP sending (via PHPMailer and other tools)
* uses PDO for database access for sure, has nice DatabaseFactory (in case your project goes big)
* uses URL rewriting ("beautiful URLs")
* proper split of application and public files (requests only go into /public)
* uses Composer to load external dependencies (PHPMailer, Captcha-Generator, etc.)
* uses Composer to load external dependencies (PHPMailer, Captcha-Generator, etc.) for sure
* fits PSR-0/1/2/4 coding guidelines
* uses [Post-Redirect-Get pattern](https://en.wikipedia.org/wiki/Post/Redirect/Get) for nice application flow
* masses of comments
* is actively developed, maintained and bug-fixed

### Planned features

* A real documentation (currently there's none, but the code is well commented)

### Live-Demo <a name="live-demo"></a>

See a [live demo here](http://demo-huge.php-login.net) and [the server's phpinfo() here](http://demo-huge.php-login.net/info.php).
See a [live demo of older 3.0 version here](http://demo-huge.php-login.net) and [the server's phpinfo() here](http://demo-huge.php-login.net/info.php).

### Support the project <a name="support"></a>

There a lot of work behind this project. I might save you hundreds, maybe thousands of hours of work (calculate that
There is a lot of work behind this project. I might save you hundreds, maybe thousands of hours of work (calculate that
in developer costs). So when you are earning money by using HUGE, be fair and give something back to open-source.
HUGE is totally free to private and commercial use.

Expand Down Expand Up @@ -335,8 +348,8 @@ A real documentation is in the making. Until then, please have a look at the cod
features to get an idea how things work, it's quite obvious when you look at the controller files, the model files and
how data is shown in the view files. A big sorry that there's no documentation yet, but time is rare :)

TODO: Full documentation
TODO: Basic examples on how to do things
- TODO: Full documentation
- TODO: Basic examples on how to do things

#### The different user roles

Expand All @@ -352,6 +365,32 @@ Normal users have a value of `1` or `2` inside the database table field `user_ac
registered users are normal users with user role 1 for sure.

See the "Testing with demo users" section of this readme for more info.

#### An introduction into the CSRF features

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,
the application puts a "random string" inside the form (as a hidden input field), generated via Csrf::makeToken()
(application/core/Csrf.php), which also saves this token to the session. When the form is submitted, the application
checks if the POST request contains exactly the form token that is inside the session.

This CSRF prevention feature is currently implemented on the login form process (see *application/view/login/index.php*)
and user name change form process (see *application/view/login/editUsername.php*), most other forms are not security-
critical and should stay as simple as possible.

A big thanks to OmarElGabry for implementing this!

#### Troubleshooting & Glitches

* In 3.0 and 3.1 a user could log into the application from different devices / browsers / locations. This was intended
behaviour as this is standard in most web applications these days. In 3.2 still feature is "missing" by default, a
user will only be able to log in from one browser at the same time. This is a security improvement, but for sure not
optimal for many developers. The plan is to implement a config switch that will allow / disallow logins from multiple
browsers.
* Using this on a sub-domain ? You might get problems with the cookies in IE11. Fix this by replacing "/" with "./" of
the cookie location COOKIE_PATH inside application/config/config.xxx.php!
Check [ticket #733](https://github.com/panique/huge/issues/733) for more info. Thanks to jahbiuabft for figuring this
out. Update: There's another ticket focusing on the same issue: [ticket #681](https://github.com/panique/huge/issues/681)

### Community-provided features & feature discussions <a name="community"></a>

Expand All @@ -360,18 +399,51 @@ to go into the main version of HUGE, but have a look into these tickets if you a

- [Caching system](https://github.com/panique/huge/issues/643)
- [ReCaptcha as captcha](https://github.com/panique/huge/issues/665)
- [Internationalization feature](https://github.com/panique/huge/issues/582)
- [Using controller A inside controller B](https://github.com/panique/huge/issues/706)
- [HTML mails](https://github.com/panique/huge/issues/738)

### Future of the project: As simple as possible!
### Future of the project: As simple as possible! <a name="future"></a>

The idea of this project was (or is) to provide a super-simple barebone application with a full user authentication
The idea of this project was to provide a super-simple barebone application with a full user authentication
system inside. For future development it might be cool to avoid feature hell and overbloated code, so please let's keep
this project simple, clean and minimal with these few "rules": :)
this project simple, clean and minimal with these few "rules" (and more on this inside this ticket:
[Keep the project as simple as possible](https://github.com/panique/huge/issues/664).):

1. Reduce features to the bare minimum.
2. Don't implement features that are not needed by most users.
3. Only build everything for the most common use case (like MySQL, not PostGre, NoSQL etc).

More on this ticket: [Keep the project as simple as possible](https://github.com/panique/huge/issues/664).
#### List of feature ideas

Open-source is a great thing, and projects live from community-contributed feature for sure. As this project is highly
security-related and mainly just a free-time one-man show, new features mean a lot of work, reviewing, testing,
corrections, and making sure it runs perfectly in every possible scenario. As I simply don't have the time to do this,
I would kindly ask you **not** to commit new features when they are not really basic, very small and well-written,
and if you miss a feature, then please try to write this on your own and commit it to the project.

To avoid unnecessary work for all of us I would kindly recommend everybody to use HUGE for simple project that only
need the features that already exist, and if you really need a RESTful architecture, migrations, routing, 2FA etc,
then it's easier, cleaner and faster to simply use Laravel, Symfony or Zend.

However, here are the community-suggested possible features, taken from lots of tickets. Feel free to implement them
into your forks of the project:

* OAuth2 implementation (let your users create accounts and login via 3rd party auth, like Facebook, Twitter, GitHub,
etc). As this is a lot of work and would make the project much more complicated it might make sense to do this in a
fork or totally skip it. (see [Ticket #528](https://github.com/panique/huge/issues/528))
* Router (map all URLs to according controller-methods inside one file), [Ticket 727](https://github.com/panique/huge/issues/727)
* RESTful architecture (see [ticket #488](https://github.com/panique/huge/issues/488) for discussion)
* Horizontal MySQL scaling (see [ticket #423](https://github.com/panique/huge/issues/423) for discussion)
* Modules / middleware
* Logging
* Two-Factor-Authentication (see [ticket #732](https://github.com/panique/huge/issues/732))
* Controller-less URLs (see [ticket #704](https://github.com/panique/huge/issues/704))
* Email-re-validation after email change (see [ticket #705](https://github.com/panique/huge/issues/705))
* Connect to multiple databases (see [ticket #702](https://github.com/panique/huge/issues/702))
* A deeper user role system (see [ticket #701](https://github.com/panique/huge/issues/701),
[pull-request #691](https://github.com/panique/huge/pull/691)),
[ticket #603](https://github.com/panique/huge/issues/603)

### Why is there no support forum (anymore) ? <a name="why-no-support-forum"></a>

Expand Down Expand Up @@ -454,6 +526,14 @@ More here on Stackflow: [How to prevent favicon.ico requests?](http://stackoverf
- [Some basic "benchmarks" of all PHP hash/salt algorithms](https://github.com/panique/huge/wiki/Which-hashing-&-salting-algorithm-should-be-used-%3F)
- [How to prevent PHP sessions being shared between different apache vhosts / different applications](http://www.dev-metal.com/prevent-php-sessions-shared-different-apache-vhosts-different-applications/)

## Interesting links regarding user authentication and application security

- [interesting article about password resets (by Troy Hunt, security expert)](http://www.troyhunt.com/2012/05/everything-you-ever-wanted-to-know.html)
- Password-Free Email Logins: [Ticket & discussion](https://github.com/panique/huge/issues/674), [article](http://techcrunch.com/2015/06/30/blogging-site-medium-rolls-out-password-free-email-logins/?ref=webdesignernews.com)
- Logging in via QR code: [Ticket & discussion](https://github.com/panique/huge/issues/290), [english article](https://www.grc.com/sqrl/sqrl.htm),
[german article](http://www.phpgangsta.de/sesam-oeffne-dich-sicher-einloggen-im-internetcafe),
[repo](https://github.com/PHPGangsta/Sesame), [live-demo](http://sesame.phpgangsta.de/). Big thanks to *PHPGangsta* for writing this!

### Side-facts

1. Weird! When I renamed php-login to HUGE (to get rid off the too generic project name and to make it fitting nicely
Expand All @@ -466,4 +546,4 @@ More here on Stackflow: [How to prevent favicon.ico requests?](http://stackoverf
### My blog

I'm also blogging at **[Dev Metal](http://www.dev-metal.com)**, have a visit if you like. Mostly PHP stuff, conference
talks and general IT issues.
talks and general IT issues.
7 changes: 4 additions & 3 deletions application/_installation/02-create-table-users.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CREATE TABLE IF NOT EXISTS `huge`.`users` (
`user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'auto incrementing user_id of each user, unique index',
`session_id` varchar(48) DEFAULT NULL COMMENT 'stores session cookie id to prevent session concurrency',
`user_name` varchar(64) COLLATE utf8_unicode_ci NOT NULL COMMENT 'user''s name, unique',
`user_password_hash` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'user''s password in salted and hashed format',
`user_email` varchar(64) COLLATE utf8_unicode_ci NOT NULL COMMENT 'user''s email, unique',
Expand All @@ -22,9 +23,9 @@ CREATE TABLE IF NOT EXISTS `huge`.`users` (
UNIQUE KEY `user_email` (`user_email`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='user data';

INSERT INTO `huge`.`users` (`user_id`, `user_name`, `user_password_hash`, `user_email`, `user_active`, `user_deleted`, `user_account_type`,
INSERT INTO `huge`.`users` (`user_id`, `session_id`, `user_name`, `user_password_hash`, `user_email`, `user_active`, `user_deleted`, `user_account_type`,
`user_has_avatar`, `user_remember_me_token`, `user_creation_timestamp`, `user_suspension_timestamp`, `user_last_login_timestamp`,
`user_failed_logins`, `user_last_failed_login`, `user_activation_hash`, `user_password_reset_hash`,
`user_password_reset_timestamp`, `user_provider_type`) VALUES
(1, 'demo', '$2y$10$OvprunjvKOOhM1h9bzMPs.vuwGIsOqZbw88rzSyGCTJTcE61g5WXi', 'demo@demo.com', 1, 0, 7, 0, NULL, 1422205178, NULL, 1422209189, 0, NULL, NULL, NULL, NULL, 'DEFAULT'),
(2, 'demo2', '$2y$10$OvprunjvKOOhM1h9bzMPs.vuwGIsOqZbw88rzSyGCTJTcE61g5WXi', 'demo2@demo.com', 1, 0, 1, 0, NULL, 1422205178, NULL, 1422209189, 0, NULL, NULL, NULL, NULL, 'DEFAULT');
(1, NULL, 'demo', '$2y$10$OvprunjvKOOhM1h9bzMPs.vuwGIsOqZbw88rzSyGCTJTcE61g5WXi', 'demo@demo.com', 1, 0, 7, 0, NULL, 1422205178, NULL, 1422209189, 0, NULL, NULL, NULL, NULL, 'DEFAULT'),
(2, NULL, 'demo2', '$2y$10$OvprunjvKOOhM1h9bzMPs.vuwGIsOqZbw88rzSyGCTJTcE61g5WXi', 'demo2@demo.com', 1, 0, 1, 0, NULL, 1422205178, NULL, 1422209189, 0, NULL, NULL, NULL, NULL, 'DEFAULT');
19 changes: 19 additions & 0 deletions application/config/config.development.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,22 @@
* COOKIE_PATH is the path the cookie is valid on, usually "/" to make it valid on the whole domain.
* @see http://stackoverflow.com/q/9618217/1114320
* @see php.net/manual/en/function.setcookie.php
*
* COOKIE_DOMAIN: The domain where the cookie is valid for.
* COOKIE_DOMAIN mightn't work with "localhost", ".localhost", "127.0.0.1", or ".127.0.0.1". If so, leave it as empty string, false or null.
* @see http://stackoverflow.com/questions/1134290/cookies-on-localhost-with-explicit-domain
* @see http://php.net/manual/en/function.setcookie.php#73107
*
* COOKIE_SECURE: If the cookie will be transferred through secured connection(SSL). It's highly recommended to set it to true if you have secured connection.
* COOKIE_HTTP: If set to true, Cookies that can't be accessed by JS - Highly recommended!
* SESSION_RUNTIME: How long should a session cookie be valid by seconds, 604800 = 1 week.
*/
'COOKIE_RUNTIME' => 1209600,
'COOKIE_PATH' => '/',
'COOKIE_DOMAIN' => "",
'COOKIE_SECURE' => false,
'COOKIE_HTTP' => true,
'SESSION_RUNTIME' => 604800,
/**
* Configuration for: Avatars/Gravatar support
* Set to true if you want to use "Gravatar(s)", a service that automatically gets avatar pictures via using email
Expand All @@ -99,6 +112,12 @@
'AVATAR_SIZE' => 44,
'AVATAR_JPEG_QUALITY' => 85,
'AVATAR_DEFAULT_IMAGE' => 'default.jpg',
/**
* Configuration for: Encryption Keys
*
*/
'ENCRYPTION_KEY' => '6#x0gÊìf^25cL1f$08&',
'HMAC_SALT' => '8qk9c^4L6d#15tM8z7n0%',
/**
* Configuration for: Email server credentials
*
Expand Down
13 changes: 13 additions & 0 deletions application/controller/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ public function index()
*/
public function login()
{

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

// perform the login method, put result (true or false) into $login_successful
$login_successful = LoginModel::login(
Request::post('user_name'), Request::post('user_password'), Request::post('set_remember_me_cookie')
Expand All @@ -60,6 +66,7 @@ public function logout()
{
LoginModel::logout();
Redirect::home();
exit();
}

/**
Expand Down Expand Up @@ -113,6 +120,12 @@ public function editUsername()
public function editUsername_action()
{
Auth::checkAuthentication();

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

UserModel::editUserName(Request::post('user_name'));
Redirect::to('login/index');
}
Expand Down
Loading

0 comments on commit 9ef38da

Please sign in to comment.