Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Initial commit of secure login project
  • Loading branch information
john committed Apr 23, 2017
1 parent 03e6fb6 commit 3481a87
Show file tree
Hide file tree
Showing 32 changed files with 873 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
vendor/
20 changes: 20 additions & 0 deletions app/config/config.php
@@ -0,0 +1,20 @@
<?php

/* Configuration for Project */
class Config {
const server_name = 'localhost';
const secret_key = 'dfJdHtKsNiMrr0JV6ebvD9CbTiHugBiDwCRkAJxu9KtXU+ig/fZlWNHr6xnZaeYFrempQFIjvxiYf3NTWOJq0w==';

const my_netid = 'jwb11006';
const db_host = 'localhost';

const db_name = 'db_jwb11006';
const db_user = 'db_jwb11006';
const db_pass = 'luckycharms';

const cookie_path = "/security_prj1";
const cookie_domain = "";
const cookie_name = 'csp1_jwb11006';
}

?>
36 changes: 36 additions & 0 deletions app/controller/UserController.php
@@ -0,0 +1,36 @@
<?php
include(APP_DIR . 'model/User.php');

class UserController {

public static function authenticate($request) {
$username = htmlspecialchars($request['username']);
$password = htmlspecialchars($request['password']);

$user = User::get($username);

if (!$user) {
return null;
}

if (password_verify($password, $user->password)) {
$user->login_attempts = 0;
$user->save();
return $user;
} else {
$user->login_attempts++;
$user->save();
return null;
}
}

public static function create($request) {
$username = htmlspecialchars($request['username']);
$password = htmlspecialchars($request['password']);
$user = new User;
$user->username = $username;
$user->password = password_hash($password, PASSWORD_DEFAULT);
$user->save();
}
}
?>
10 changes: 10 additions & 0 deletions app/database/Database.php
@@ -0,0 +1,10 @@
<?php
include_once(APP_DIR . 'config/config.php');

class Database {
public static function connect() {
$db_str = 'mysql:host=' . Config::db_host . ';dbname=' . Config::db_name;
return new PDO($db_str, Config::db_user, Config::db_pass);
}
}
?>
38 changes: 38 additions & 0 deletions app/database/init.php
@@ -0,0 +1,38 @@
<?php
defined('APP_DIR') or define('APP_DIR', 'app/');
include_once('app/config/config.php');
include_once('app/database/Database.php');
include_once('app/model/User.php');

$dbh = new PDO('mysql:host=' . Config::db_host, Config::db_user, Config::db_pass);

/* Create database if it doesn't exist */
$dbh->exec('CREATE DATABASE IF NOT EXISTS ' . Config::db_name);

/* Connect to database */
$dbh = Database::connect();

/* Create users table if it doesn't exist */
$stmt = 'CREATE TABLE IF NOT EXISTS users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(32) NOT NULL,
password VARCHAR(64) NOT NULL,
access VARCHAR(8) NOT NULL,
login_attempts INT(6) UNSIGNED NOT NULL
)';
$dbh->exec($stmt);

/* Create user and admin if they don't exist */
$user = new User;
$user->username = 'user';
$user->password = password_hash('userpass', PASSWORD_DEFAULT);
$user->access = 'user';
$user->save();

$user = new User;
$user->username = 'admin';
$user->password = password_hash('adminpass', PASSWORD_DEFAULT);
$user->access = 'admin';
$user->save();

?>
41 changes: 41 additions & 0 deletions app/forms/change_password.php
@@ -0,0 +1,41 @@
<?php
if (isset($_GET['error'])) {
$error_message = "Incorrect password";
} else {
$error_message = '&nbsp;';
}
?>

<div class="row login-container valign-wrapper">
<div class="col l6 m8 s 10 offset-l3 offset-m2 offset-l1 valign">
<div id="login-form" class="row scale-transition scale-out">
<div class="col s12 card-panel">
<div class="row login-header"> <h5> Need to change your password? </h5> </div>
<div class="row">
<form class="col s12" action="change_password.php" method="post">
<div class="row">
<div class="input-field col s12 valign-wrapper">
<i class="material-icons prefix valign">lock</i>
<input id="password" name="password" type="password" class="validate">
<label for="password">Current password</label>
</div>
<div class="input-field col s12 valign-wrapper">
<i class="material-icons prefix valign">lock</i>
<input id="new_password" name="new_password" type="password" class="validate">
<label for="new_password">New password</label>
</div>
<button
class="btn col s4 offset-s4 waves-effect waves-light"
type="submit" name="action"
>
Change
<i class="material-icons right">send</i>
</button>
<span class="error-message col s12 center-align"> <?php echo $error_message ?> </span>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
39 changes: 39 additions & 0 deletions app/forms/create.php
@@ -0,0 +1,39 @@

<!-- Modal Structure -->
<form id="create-modal" class="modal" action="create.php" method="post">
<div class="modal-content">
<h4 class="row">Create a new user</h4>
<div class="row">
<div class="col s12">
<div class="row">
<div class="input-field col s12 valign-wrapper">
<i class="material-icons prefix valign">account_circle</i>
<input id="username" name="username" type="text" class="validate">
<label for="username">Username</label>
</div>
<div class="input-field col s12 valign-wrapper">
<i class="material-icons prefix valign">lock</i>
<input id="password" name="password" type="password" class="validate" />
<label for="password">Password</label>
</div>
<div class="input-field col s12">
<h6> Access level: </h6>
<input class="with-gap" name="access" type="radio" id="access1" value="admin" checked="checked" />
<label for="access1">Admin</label> <br />
<input class="with-gap" name="access" type="radio" id="access2" value="user" />
<label for="access2">User</label>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer input-field">
<button
class="waves-effect waves-green btn-flat"
type="submit" name="action"
onclick="Materialize.toast('User created', 4000)"
>
Create
</button>
</div>
</form>
40 changes: 40 additions & 0 deletions app/forms/edit.php
@@ -0,0 +1,40 @@
<!-- Modal Structure -->
<form id="edit-modal-<?php echo $user->id ?>" class="modal" action="create.php" method="post">
<div class="modal-content">
<h4 class="row">Edit account for <?php echo $user->username ?></h4>
<div class="row">
<div class="col s12">
<div class="row">
<input name="username" type="hidden" value="<?php echo $user->username ?>" />
<div class="input-field col s12 valign-wrapper">
<i class="material-icons prefix valign">lock</i>
<input id="password" name="password" type="password" class="validate" />
<label for="password">New password</label>
</div>
<div class="input-field col s12">
<h6> Access level: </h6>
<input
class="with-gap" name="access" type="radio"
id="access-edit1-<?php echo $user->id ?>" value="admin" checked="checked"
/>
<label for="access-edit1-<?php echo $user->id ?>">Admin</label> <br />
<input
class="with-gap" name="access" type="radio"
id="access-edit2-<?php echo $user->id ?>" value="user"
/>
<label for="access-edit2-<?php echo $user->id ?>">User</label>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer input-field">
<button
class="waves-effect waves-green btn-flat"
type="submit" name="action"
onclick="Materialize.toast('User updated', 4000)"
>
Change
</button>
</div>
</form>
43 changes: 43 additions & 0 deletions app/forms/login.php
@@ -0,0 +1,43 @@
<?php
if (isset($_GET['error']) && $_GET['error'] == '1') {
$error_message = "Incorrect username or password";
} else if (isset($_GET['error']) && $_GET['error'] == '2') {
$error_message = "Too many login attempts. Contact the system administrator.";
} else {
$error_message = '&nbsp;';
}
?>

<div class="row login-container valign-wrapper">
<div class="col l6 m8 s 10 offset-l3 offset-m2 offset-l1 valign">
<div id="login-form" class="row scale-transition scale-out">
<div class="col s12 card-panel">
<div class="row login-header"> <h5> Please enter your credentials </h5> </div>
<div class="row">
<form class="col s12" action="login.php" method="post">
<div class="row">
<div class="input-field col s12 valign-wrapper">
<i class="material-icons prefix valign">account_circle</i>
<input id="username" name="username" type="text" class="validate">
<label for="username">Username</label>
</div>
<div class="input-field col s12 valign-wrapper">
<i class="material-icons prefix valign">lock</i>
<input id="password" name="password" type="password" class="validate">
<label for="password">Password</label>
</div>
<button
class="btn col s4 offset-s4 waves-effect waves-light"
type="submit" name="action"
>
SIGN IN
<i class="material-icons right">send</i>
</button>
<span class="error-message col s12 center-align"> <?php echo $error_message ?> </span>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
24 changes: 24 additions & 0 deletions app/include/http.php
@@ -0,0 +1,24 @@
<?php

class Http {

public static function redirect($url, $params = []) {
$query = empty($params) ? '' : '?' . http_build_query($params);
header('Location: ' . $url . $query);
exit();
}

public static function cookie($name) {
return isset($_COOKIE[$name]) ? $_COOKIE[$name] : null;
}

public static function remove_cookie($name) {
setcookie($name, "", time() - 3600);
}

public static function post_params() {
return $_POST;
}

}
?>

0 comments on commit 3481a87

Please sign in to comment.