forked from Business/BinStack
Create template based on SSO code
This commit is contained in:
commit
16cbf2a5f1
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
vendor
|
||||||
|
settings.php
|
||||||
|
nbproject/private
|
||||||
|
database_model.mwb.bak
|
62
action.php
Normal file
62
action.php
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make things happen when buttons are pressed and forms submitted.
|
||||||
|
*/
|
||||||
|
use LdapTools\LdapManager;
|
||||||
|
use LdapTools\Object\LdapObjectType;
|
||||||
|
|
||||||
|
require_once __DIR__ . "/required.php";
|
||||||
|
|
||||||
|
dieifnotloggedin();
|
||||||
|
|
||||||
|
require_once __DIR__ . "/lib/login.php";
|
||||||
|
require_once __DIR__ . "/lib/worst_passwords.php";
|
||||||
|
|
||||||
|
function returnToSender($msg, $arg = "") {
|
||||||
|
global $VARS;
|
||||||
|
if ($arg == "") {
|
||||||
|
header("Location: app.php?page=" . urlencode($VARS['source']) . "&msg=" . $msg);
|
||||||
|
} else {
|
||||||
|
header("Location: app.php?page=" . urlencode($VARS['source']) . "&msg=$msg&arg=$arg");
|
||||||
|
}
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($VARS['action']) {
|
||||||
|
case "signout":
|
||||||
|
session_destroy();
|
||||||
|
header('Location: index.php');
|
||||||
|
die("Logged out.");
|
||||||
|
case "chpasswd":
|
||||||
|
if ($_SESSION['password'] == $VARS['oldpass']) {
|
||||||
|
if ($VARS['newpass'] == $VARS['conpass']) {
|
||||||
|
$passrank = checkWorst500List($VARS['newpass']);
|
||||||
|
if ($passrank !== FALSE) {
|
||||||
|
returnToSender("password_500", $passrank);
|
||||||
|
}
|
||||||
|
if (strlen($VARS['newpass']) < MIN_PASSWORD_LENGTH) {
|
||||||
|
returnToSender("weak_password");
|
||||||
|
}
|
||||||
|
|
||||||
|
$database->update('accounts', ['password' => encryptPassword($VARS['newpass'])], ['uid' => $_SESSION['uid']]);
|
||||||
|
$_SESSION['password'] = $VARS['newpass'];
|
||||||
|
returnToSender("password_updated");
|
||||||
|
} else {
|
||||||
|
returnToSender("new_password_mismatch");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
returnToSender("old_password_mismatch");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "add2fa":
|
||||||
|
if (is_empty($VARS['secret'])) {
|
||||||
|
returnToSender("invalid_parameters");
|
||||||
|
}
|
||||||
|
$database->update('accounts', ['authsecret' => $VARS['secret']], ['uid' => $_SESSION['uid']]);
|
||||||
|
returnToSender("2fa_enabled");
|
||||||
|
case "rm2fa":
|
||||||
|
$database->update('accounts', ['authsecret' => ""], ['uid' => $_SESSION['uid']]);
|
||||||
|
returnToSender("2fa_removed");
|
||||||
|
break;
|
||||||
|
}
|
128
app.php
Normal file
128
app.php
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . "/required.php";
|
||||||
|
|
||||||
|
if ($_SESSION['loggedin'] != true) {
|
||||||
|
header('Location: index.php');
|
||||||
|
die("Session expired. Log in again to continue.");
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once __DIR__ . "/pages.php";
|
||||||
|
|
||||||
|
$pageid = "home";
|
||||||
|
if (!is_empty($_GET['page'])) {
|
||||||
|
$pg = strtolower($_GET['page']);
|
||||||
|
$pg = preg_replace('/[^0-9a-z_]/', "", $pg);
|
||||||
|
if (array_key_exists($pg, PAGES) && file_exists(__DIR__ . "/pages/" . $pg . ".php")) {
|
||||||
|
$pageid = $pg;
|
||||||
|
} else {
|
||||||
|
$pageid = "404";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" contgreent="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<title><?php echo SITE_TITLE; ?></title>
|
||||||
|
|
||||||
|
<link href="static/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link href="static/css/font-awesome.min.css" rel="stylesheet">
|
||||||
|
<link href="static/css/app.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 col-sm-offset-3 col-md-offset-4 col-lg-offset-4">
|
||||||
|
<img class="img-responsive banner-image" src="static/img/banner.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<nav class="navbar navbar-inverse">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse">
|
||||||
|
<span class="sr-only">Toggle navigation</span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
<a class="navbar-brand" href="app.php?page=home">
|
||||||
|
<?php
|
||||||
|
// add breadcrumb-y thing
|
||||||
|
//lang("home");
|
||||||
|
//echo " <i class=\"fa fa-caret-right\"></i> ";
|
||||||
|
lang(PAGES[$pageid]['title']);
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse" id="navbar-collapse">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
</ul>
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-gears fa-fw"></i> <?php lang("options") ?> <span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li><a href="app.php?page=security"><i class="fa fa-lock fa-fw"></i> <?php lang("account security") ?></a></li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li><a href="action.php?action=signout"><i class="fa fa-sign-out fa-fw"></i> <?php lang("sign out") ?></a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<?php
|
||||||
|
// Alert messages
|
||||||
|
if (!is_empty($_GET['msg']) && array_key_exists($_GET['msg'], MESSAGES)) {
|
||||||
|
// optional string generation argument
|
||||||
|
if (is_empty($_GET['arg'])) {
|
||||||
|
$alertmsg = lang(MESSAGES[$_GET['msg']]['string'], false);
|
||||||
|
} else {
|
||||||
|
$alertmsg = lang2(MESSAGES[$_GET['msg']]['string'], ["arg" => $_GET['arg']], false);
|
||||||
|
}
|
||||||
|
$alerttype = MESSAGES[$_GET['msg']]['type'];
|
||||||
|
$alerticon = "square-o";
|
||||||
|
switch (MESSAGES[$_GET['msg']]['type']) {
|
||||||
|
case "danger":
|
||||||
|
$alerticon = "times";
|
||||||
|
break;
|
||||||
|
case "warning":
|
||||||
|
$alerticon = "exclamation-triangle";
|
||||||
|
break;
|
||||||
|
case "info":
|
||||||
|
$alerticon = "info-circle";
|
||||||
|
break;
|
||||||
|
case "success":
|
||||||
|
$alerticon = "check";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
echo <<<END
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 col-sm-offset-3 col-md-offset-4 col-lg-offset-4">
|
||||||
|
<div class="alert alert-dismissible alert-$alerttype">
|
||||||
|
<button type="button" class="close">×</button>
|
||||||
|
<i class="fa fa-$alerticon"></i> $alertmsg
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
END;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div>
|
||||||
|
<?php
|
||||||
|
include_once __DIR__ . '/pages/' . $pageid . ".php";
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<?php echo LICENSE_TEXT; ?><br />
|
||||||
|
Copyright © <?php echo date('Y'); ?> <?php echo COPYRIGHT_NAME; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="static/js/jquery-3.2.1.min.js"></script>
|
||||||
|
<script src="static/js/bootstrap.min.js"></script>
|
||||||
|
<script src="static/js/app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
16
composer.json
Normal file
16
composer.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "netsyms/web-app-template",
|
||||||
|
"description": "Simple framework for rapid webapp development",
|
||||||
|
"type": "project",
|
||||||
|
"require": {
|
||||||
|
"catfan/medoo": "^1.2",
|
||||||
|
"spomky-labs/otphp": "^8.3"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Skylar Ittner",
|
||||||
|
"email": "admin@netsyms.com"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
461
composer.lock
generated
Normal file
461
composer.lock
generated
Normal file
@ -0,0 +1,461 @@
|
|||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "51c1672b4dea32e60865b4c0cd9ff8e1",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "beberlei/assert",
|
||||||
|
"version": "v2.7.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/beberlei/assert.git",
|
||||||
|
"reference": "3ee3bc468a3ce4bbfc3d74f53c6cdb5242d39d1a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/beberlei/assert/zipball/3ee3bc468a3ce4bbfc3d74f53c6cdb5242d39d1a",
|
||||||
|
"reference": "3ee3bc468a3ce4bbfc3d74f53c6cdb5242d39d1a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": ">=5.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"friendsofphp/php-cs-fixer": "^2.1.1",
|
||||||
|
"phpunit/phpunit": "^4|^5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Assert\\": "lib/Assert"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"lib/Assert/functions.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-2-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Benjamin Eberlei",
|
||||||
|
"email": "kontakt@beberlei.de",
|
||||||
|
"role": "Lead Developer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Richard Quadling",
|
||||||
|
"email": "rquadling@gmail.com",
|
||||||
|
"role": "Collaborator"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Thin assertion library for input validation in business models.",
|
||||||
|
"keywords": [
|
||||||
|
"assert",
|
||||||
|
"assertion",
|
||||||
|
"validation"
|
||||||
|
],
|
||||||
|
"time": "2017-03-14T18:06:52+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "catfan/medoo",
|
||||||
|
"version": "v1.2.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/catfan/Medoo.git",
|
||||||
|
"reference": "b5a788c90c44db0f978512c890cb6962af4685e8"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/catfan/Medoo/zipball/b5a788c90c44db0f978512c890cb6962af4685e8",
|
||||||
|
"reference": "b5a788c90c44db0f978512c890cb6962af4685e8",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-pdo": "*",
|
||||||
|
"php": ">=5.4"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-pdo_dblib": "For MSSQL or Sybase databases on Linux/UNIX platform",
|
||||||
|
"ext-pdo_mysql": "For MySQL or MariaDB databases",
|
||||||
|
"ext-pdo_oci": "For Oracle databases",
|
||||||
|
"ext-pdo_pqsql": "For PostgreSQL databases",
|
||||||
|
"ext-pdo_sqlite": "For SQLite databases",
|
||||||
|
"ext-pdo_sqlsrv": "For MSSQL databases on Windows platform"
|
||||||
|
},
|
||||||
|
"type": "framework",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Medoo\\": "/src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Angel Lai",
|
||||||
|
"email": "angel@catfan.me"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "The Lightest PHP database framework to accelerate development",
|
||||||
|
"homepage": "http://medoo.in",
|
||||||
|
"keywords": [
|
||||||
|
"database",
|
||||||
|
"lightweight",
|
||||||
|
"mssql",
|
||||||
|
"mysql",
|
||||||
|
"php framework",
|
||||||
|
"sql",
|
||||||
|
"sqlite"
|
||||||
|
],
|
||||||
|
"time": "2017-02-17T16:05:35+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "christian-riesen/base32",
|
||||||
|
"version": "1.3.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/ChristianRiesen/base32.git",
|
||||||
|
"reference": "0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/ChristianRiesen/base32/zipball/0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa",
|
||||||
|
"reference": "0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "4.*",
|
||||||
|
"satooshi/php-coveralls": "0.*"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.1.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Base32\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Christian Riesen",
|
||||||
|
"email": "chris.riesen@gmail.com",
|
||||||
|
"homepage": "http://christianriesen.com",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Base32 encoder/decoder according to RFC 4648",
|
||||||
|
"homepage": "https://github.com/ChristianRiesen/base32",
|
||||||
|
"keywords": [
|
||||||
|
"base32",
|
||||||
|
"decode",
|
||||||
|
"encode",
|
||||||
|
"rfc4648"
|
||||||
|
],
|
||||||
|
"time": "2016-05-05T11:49:03+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "paragonie/random_compat",
|
||||||
|
"version": "v2.0.10",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/paragonie/random_compat.git",
|
||||||
|
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/634bae8e911eefa89c1abfbf1b66da679ac8f54d",
|
||||||
|
"reference": "634bae8e911eefa89c1abfbf1b66da679ac8f54d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.2.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "4.*|5.*"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"lib/random.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Paragon Initiative Enterprises",
|
||||||
|
"email": "security@paragonie.com",
|
||||||
|
"homepage": "https://paragonie.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
|
||||||
|
"keywords": [
|
||||||
|
"csprng",
|
||||||
|
"pseudorandom",
|
||||||
|
"random"
|
||||||
|
],
|
||||||
|
"time": "2017-03-13T16:27:32+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "spomky-labs/otphp",
|
||||||
|
"version": "v8.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Spomky-Labs/otphp.git",
|
||||||
|
"reference": "8c90e16ba48fe7c306832611e22c5bad2d663a98"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/8c90e16ba48fe7c306832611e22c5bad2d663a98",
|
||||||
|
"reference": "8c90e16ba48fe7c306832611e22c5bad2d663a98",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"beberlei/assert": "^2.4",
|
||||||
|
"christian-riesen/base32": "^1.1",
|
||||||
|
"paragonie/random_compat": "^2.0",
|
||||||
|
"php": "^5.5|^7.0",
|
||||||
|
"symfony/polyfill-mbstring": "^1.1",
|
||||||
|
"symfony/polyfill-php56": "^1.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.0|^5.0",
|
||||||
|
"satooshi/php-coveralls": "^1.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "8.2.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"OTPHP\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Florent Morselli",
|
||||||
|
"homepage": "https://github.com/Spomky"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "All contributors",
|
||||||
|
"homepage": "https://github.com/Spomky-Labs/otphp/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator",
|
||||||
|
"homepage": "https://github.com/Spomky-Labs/otphp",
|
||||||
|
"keywords": [
|
||||||
|
"FreeOTP",
|
||||||
|
"RFC 4226",
|
||||||
|
"RFC 6238",
|
||||||
|
"google authenticator",
|
||||||
|
"hotp",
|
||||||
|
"otp",
|
||||||
|
"totp"
|
||||||
|
],
|
||||||
|
"time": "2016-12-08T10:46:02+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-mbstring",
|
||||||
|
"version": "v1.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||||
|
"reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
|
||||||
|
"reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-mbstring": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.3-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for the Mbstring extension",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"mbstring",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"time": "2016-11-14T01:06:16+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-php56",
|
||||||
|
"version": "v1.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-php56.git",
|
||||||
|
"reference": "1dd42b9b89556f18092f3d1ada22cb05ac85383c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/1dd42b9b89556f18092f3d1ada22cb05ac85383c",
|
||||||
|
"reference": "1dd42b9b89556f18092f3d1ada22cb05ac85383c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3",
|
||||||
|
"symfony/polyfill-util": "~1.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.3-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Php56\\": ""
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"time": "2016-11-14T01:06:16+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-util",
|
||||||
|
"version": "v1.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-util.git",
|
||||||
|
"reference": "746bce0fca664ac0a575e465f65c6643faddf7fb"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-util/zipball/746bce0fca664ac0a575e465f65c6643faddf7fb",
|
||||||
|
"reference": "746bce0fca664ac0a575e465f65c6643faddf7fb",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.3-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Util\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony utilities for portability of PHP codes",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compat",
|
||||||
|
"compatibility",
|
||||||
|
"polyfill",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"time": "2016-11-14T01:06:16+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": [],
|
||||||
|
"platform-dev": []
|
||||||
|
}
|
BIN
database_model.mwb
Normal file
BIN
database_model.mwb
Normal file
Binary file not shown.
117
index.php
Normal file
117
index.php
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . "/required.php";
|
||||||
|
|
||||||
|
require_once __DIR__ . "/lib/login.php";
|
||||||
|
|
||||||
|
/* Authenticate user */
|
||||||
|
$userpass_ok = false;
|
||||||
|
$multiauth = false;
|
||||||
|
if ($VARS['progress'] == "1") {
|
||||||
|
if (authenticate_user($VARS['username'], $VARS['password'])) {
|
||||||
|
switch (get_account_status($VARS['username'])) {
|
||||||
|
case "LOCKED_OR_DISABLED":
|
||||||
|
$alert = lang("account locked", false);
|
||||||
|
break;
|
||||||
|
case "TERMINATED":
|
||||||
|
$alert = lang("account terminated", false);
|
||||||
|
break;
|
||||||
|
case "CHANGE_PASSWORD":
|
||||||
|
$alert = lang("password expired", false);
|
||||||
|
case "NORMAL":
|
||||||
|
$userpass_ok = true;
|
||||||
|
break;
|
||||||
|
case "ALERT_ON_ACCESS":
|
||||||
|
sendLoginAlertEmail($VARS['username']);
|
||||||
|
$userpass_ok = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ($userpass_ok) {
|
||||||
|
if (userHasTOTP($VARS['username'])) {
|
||||||
|
$multiauth = true;
|
||||||
|
} else {
|
||||||
|
doLoginUser($VARS['username'], $VARS['password']);
|
||||||
|
header('Location: app.php');
|
||||||
|
die("Logged in, go to app.php");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$alert = lang("login incorrect", false);
|
||||||
|
}
|
||||||
|
} else if ($VARS['progress'] == "2") {
|
||||||
|
if (verifyTOTP($VARS['username'], $VARS['authcode'])) {
|
||||||
|
doLoginUser($VARS['username'], $VARS['password']);
|
||||||
|
header('Location: app.php');
|
||||||
|
die("Logged in, go to app.php");
|
||||||
|
} else {
|
||||||
|
$alert = lang("2fa incorrect", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" contgreent="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<title><?php echo SITE_TITLE; ?></title>
|
||||||
|
|
||||||
|
<link href="static/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link href="static/css/app.css" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 col-sm-offset-3 col-md-offset-4 col-lg-offset-4">
|
||||||
|
<div>
|
||||||
|
<img class="img-responsive banner-image" src="static/img/banner.png" />
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-primary">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title"><?php lang("sign in"); ?></h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form action="" method="POST">
|
||||||
|
<?php
|
||||||
|
if (!is_empty($alert)) {
|
||||||
|
?>
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<?php echo $alert; ?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($multiauth != true) {
|
||||||
|
?>
|
||||||
|
<input type="text" class="form-control" name="username" placeholder="<?php lang("username"); ?>" required="required" autofocus /><br />
|
||||||
|
<input type="password" class="form-control" name="password" placeholder="<?php lang("password"); ?>" required="required" /><br />
|
||||||
|
<input type="hidden" name="progress" value="1" />
|
||||||
|
<?php
|
||||||
|
} else if ($multiauth) {
|
||||||
|
?>
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<?php lang("2fa prompt"); ?>
|
||||||
|
</div>
|
||||||
|
<input type="text" class="form-control" name="authcode" placeholder="<?php lang("authcode"); ?>" required="required" autofocus /><br />
|
||||||
|
<input type="hidden" name="progress" value="2" />
|
||||||
|
<input type="hidden" name="username" value="<?php echo $VARS['username']; ?>" />
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<?php lang("continue"); ?>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<?php echo LICENSE_TEXT; ?><br />
|
||||||
|
Copyright © <?php echo date('Y'); ?> <?php echo COPYRIGHT_NAME; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="static/js/jquery-3.2.1.min.js"></script>
|
||||||
|
<script src="static/js/bootstrap.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
42
lang/en_us.php
Normal file
42
lang/en_us.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
define("STRINGS", [
|
||||||
|
"sign in" => "Sign In",
|
||||||
|
"username" => "Username",
|
||||||
|
"password" => "Password",
|
||||||
|
"continue" => "Continue",
|
||||||
|
"authcode" => "Authentication code",
|
||||||
|
"2fa prompt" => "Enter the six-digit code from your mobile authenticator app.",
|
||||||
|
"2fa incorrect" => "Authentication code incorrect.",
|
||||||
|
"login incorrect" => "Login incorrect.",
|
||||||
|
"account locked" => "This account has been disabled. Contact technical support.",
|
||||||
|
"password expired" => "You must change your password before continuing.",
|
||||||
|
"account terminated" => "Account terminated. Access denied.",
|
||||||
|
"account state error" => "Your account state is not stable. Log out, restart your browser, and try again.",
|
||||||
|
"password on 500 list" => "The given password is ranked number {arg} out of the 500 most common passwords. Try a different one.",
|
||||||
|
"welcome user" => "Welcome, {user}!",
|
||||||
|
"change password" => "Change password",
|
||||||
|
"security options" => "Security options",
|
||||||
|
"account security" => "Account security",
|
||||||
|
"sign out" => "Sign out",
|
||||||
|
"settings" => "Settings",
|
||||||
|
"options" => "Options",
|
||||||
|
"404 error" => "404 Error",
|
||||||
|
"page not found" => "Page not found.",
|
||||||
|
"current password incorrect" => "The current password is incorrect. Try again.",
|
||||||
|
"new password mismatch" => "The new passwords did not match. Try again.",
|
||||||
|
"weak password" => "Password does not meet requirements.",
|
||||||
|
"password updated" => "Password updated successfully.",
|
||||||
|
"setup 2fa" => "Setup 2-factor authentication",
|
||||||
|
"2fa removed" => "2-factor authentication disabled.",
|
||||||
|
"2fa enabled" => "2-factor authentication activated.",
|
||||||
|
"remove 2fa" => "Disable 2-factor authentication",
|
||||||
|
"2fa explained" => "2-factor authentication adds more security to your account. You'll need an app such as Google Authenticator on your smartphone. When you have the app installed, you can enable 2-factor authentication by clicking the button below and scanning a QR code with the app. Whenever you sign in in the future, you'll need to input a six-digit code from your phone into the login page when prompted. You can disable 2-factor authentication from this page if you change your mind.",
|
||||||
|
"2fa active" => "2-factor authentication is active on your account. To remove 2fa, reset your authentication secret, or change to a new security device, click the button below.",
|
||||||
|
"enable 2fa" => "Enable 2-factor authentication",
|
||||||
|
"scan 2fa qrcode" => "Scan the QR Code with the authenticator app, or enter the secret key manually.",
|
||||||
|
"confirm 2fa" => "Finish setup",
|
||||||
|
"invalid parameters" => "Invalid request parameters.",
|
||||||
|
"ldap server error" => "The LDAP server returned an error: {arg}",
|
||||||
|
"home" => "Home",
|
||||||
|
]);
|
44
lang/messages.php
Normal file
44
lang/messages.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
define("MESSAGES", [
|
||||||
|
"old_password_mismatch" => [
|
||||||
|
"string" => "current password incorrect",
|
||||||
|
"type" => "danger"
|
||||||
|
],
|
||||||
|
"new_password_mismatch" => [
|
||||||
|
"string" => "new password mismatch",
|
||||||
|
"type" => "danger"
|
||||||
|
],
|
||||||
|
"weak_password" => [
|
||||||
|
"string" => "weak password",
|
||||||
|
"type" => "danger"
|
||||||
|
],
|
||||||
|
"password_updated" => [
|
||||||
|
"string" => "password updated",
|
||||||
|
"type" => "success"
|
||||||
|
],
|
||||||
|
"2fa_removed" => [
|
||||||
|
"string" => "2fa removed",
|
||||||
|
"type" => "success"
|
||||||
|
],
|
||||||
|
"2fa_enabled" => [
|
||||||
|
"string" => "2fa enabled",
|
||||||
|
"type" => "success"
|
||||||
|
],
|
||||||
|
"invalid_parameters" => [
|
||||||
|
"string" => "invalid parameters",
|
||||||
|
"type" => "danger"
|
||||||
|
],
|
||||||
|
"password_500" => [
|
||||||
|
"string" => "password on 500 list",
|
||||||
|
"type" => "danger"
|
||||||
|
],
|
||||||
|
"account_state_error" => [
|
||||||
|
"string" => "account state error",
|
||||||
|
"type" => "danger"
|
||||||
|
],
|
||||||
|
"404_error" => [
|
||||||
|
"string" => "page not found",
|
||||||
|
"type" => "info"
|
||||||
|
]
|
||||||
|
]);
|
302
lib/login.php
Normal file
302
lib/login.php
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication and account functions
|
||||||
|
*/
|
||||||
|
use Base32\Base32;
|
||||||
|
use OTPHP\TOTP;
|
||||||
|
use LdapTools\LdapManager;
|
||||||
|
use LdapTools\Connection\ADResponseCodes;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Account handling //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a user to the system. /!\ Assumes input is OK /!\
|
||||||
|
* @param string $username Username, saved in lowercase.
|
||||||
|
* @param string $password Password, will be hashed before saving.
|
||||||
|
* @param string $realname User's real legal name
|
||||||
|
* @param string $email User's email address.
|
||||||
|
* @return int The new user's ID number in the database.
|
||||||
|
*/
|
||||||
|
function adduser($username, $password, $realname, $email = null, $phone1 = "", $phone2 = "") {
|
||||||
|
global $database;
|
||||||
|
$database->debug()->insert('accounts', [
|
||||||
|
'username' => strtolower($username),
|
||||||
|
'password' => (is_null($password) ? null : encryptPassword($password)),
|
||||||
|
'realname' => $realname,
|
||||||
|
'email' => $email,
|
||||||
|
'phone1' => $phone1,
|
||||||
|
'phone2' => $phone2,
|
||||||
|
'acctstatus' => 1
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $database->id();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get where a user's account actually is.
|
||||||
|
* @param string $username
|
||||||
|
* @return string "LDAP", "LOCAL", "LDAP_ONLY", or "NONE".
|
||||||
|
*/
|
||||||
|
function account_location($username, $password) {
|
||||||
|
global $database;
|
||||||
|
$user_exists = user_exists($username);
|
||||||
|
if (!$user_exists && !LDAP_ENABLED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($user_exists) {
|
||||||
|
$userinfo = $database->select('accounts', ['password'], ['username' => $username])[0];
|
||||||
|
// if password empty, it's an LDAP user
|
||||||
|
if (is_empty($userinfo['password']) && LDAP_ENABLED) {
|
||||||
|
return "LDAP";
|
||||||
|
} else if (is_empty($userinfo['password']) && !LDAP_ENABLED) {
|
||||||
|
return "NONE";
|
||||||
|
} else {
|
||||||
|
return "LOCAL";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (user_exists_ldap($username, $password)) {
|
||||||
|
return "LDAP_ONLY";
|
||||||
|
} else {
|
||||||
|
return "NONE";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the given credentials against the database.
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @return boolean True if OK, else false
|
||||||
|
*/
|
||||||
|
function authenticate_user($username, $password) {
|
||||||
|
global $database;
|
||||||
|
global $ldap_config;
|
||||||
|
if (is_empty($username) || is_empty($password)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$loc = account_location($username, $password);
|
||||||
|
if ($loc == "NONE") {
|
||||||
|
return false;
|
||||||
|
} else if ($loc == "LOCAL") {
|
||||||
|
$hash = $database->select('accounts', ['password'], ['username' => $username, "LIMIT" => 1])[0]['password'];
|
||||||
|
return (comparePassword($password, $hash));
|
||||||
|
} else if ($loc == "LDAP") {
|
||||||
|
return authenticate_user_ldap($username, $password);
|
||||||
|
} else if ($loc == "LDAP_ONLY") {
|
||||||
|
if (authenticate_user_ldap($username, $password) === TRUE) {
|
||||||
|
try {
|
||||||
|
$user = (new LdapManager($ldap_config))->getRepository('user')->findOneByUsername($username);
|
||||||
|
var_dump($user);
|
||||||
|
adduser($user->getUsername(), null, $user->getName(), ($user->hasEmailAddress() ? $user->getEmailAddress() : null));
|
||||||
|
return true;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
sendError("LDAP error: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a username exists in the local database.
|
||||||
|
* @param String $username
|
||||||
|
*/
|
||||||
|
function user_exists($username) {
|
||||||
|
global $database;
|
||||||
|
return $database->has('accounts', ['username' => $username, "LIMIT" => QUERY_LIMIT]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the account status: NORMAL, TERMINATED, LOCKED_OR_DISABLED,
|
||||||
|
* CHANGE_PASSWORD, or ALERT_ON_ACCESS
|
||||||
|
* @global $database $database
|
||||||
|
* @param string $username
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function get_account_status($username) {
|
||||||
|
global $database;
|
||||||
|
$loc = account_location($username);
|
||||||
|
if ($loc == "LOCAL") {
|
||||||
|
$statuscode = $database->select('accounts', [
|
||||||
|
'[>]acctstatus' => [
|
||||||
|
'acctstatus' => 'statusid'
|
||||||
|
]
|
||||||
|
], [
|
||||||
|
'accounts.acctstatus',
|
||||||
|
'acctstatus.statuscode'
|
||||||
|
], [
|
||||||
|
'username' => $username,
|
||||||
|
"LIMIT" => 1
|
||||||
|
]
|
||||||
|
)[0]['statuscode'];
|
||||||
|
return $statuscode;
|
||||||
|
} else if ($loc == "LDAP") {
|
||||||
|
// TODO: Read actual account status from AD servers
|
||||||
|
return "NORMAL";
|
||||||
|
} else {
|
||||||
|
// account isn't setup properly
|
||||||
|
return "LOCKED_OR_DISABLED";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Login handling //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup $_SESSION values to log in a user
|
||||||
|
* @param string $username
|
||||||
|
*/
|
||||||
|
function doLoginUser($username, $password) {
|
||||||
|
global $database;
|
||||||
|
$userinfo = $database->select('accounts', ['email', 'uid', 'realname'], ['username' => $username])[0];
|
||||||
|
$_SESSION['username'] = $username;
|
||||||
|
$_SESSION['uid'] = $userinfo['uid'];
|
||||||
|
$_SESSION['email'] = $userinfo['email'];
|
||||||
|
$_SESSION['realname'] = $userinfo['realname'];
|
||||||
|
$_SESSION['password'] = $password; // needed for things like EWS
|
||||||
|
$_SESSION['loggedin'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an alert email to the system admin
|
||||||
|
*
|
||||||
|
* Used when an account with the status ALERT_ON_ACCESS logs in
|
||||||
|
* @param String $username the account username
|
||||||
|
*/
|
||||||
|
function sendLoginAlertEmail($username) {
|
||||||
|
// TODO: add email code
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// LDAP handling //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the given credentials against the LDAP server.
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @return mixed True if OK, else false or the error code from the server
|
||||||
|
*/
|
||||||
|
function authenticate_user_ldap($username, $password) {
|
||||||
|
global $ldap_config;
|
||||||
|
if (is_empty($username) || is_empty($password)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$ldapManager = new LdapManager($ldap_config);
|
||||||
|
$msg = "";
|
||||||
|
$code = 0;
|
||||||
|
if ($ldapManager->authenticate($username, $password, $msg, $code)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a username exists on the LDAP server.
|
||||||
|
* @global type $ldap_config
|
||||||
|
* @param type $username
|
||||||
|
* @return boolean true if yes, else false
|
||||||
|
*/
|
||||||
|
function user_exists_ldap($username, $password) {
|
||||||
|
global $ldap_config;
|
||||||
|
$ldap = new LdapManager($ldap_config);
|
||||||
|
if (!$ldap->authenticate($username, $password, $message, $code)) {
|
||||||
|
switch ($code) {
|
||||||
|
case ADResponseCodes::ACCOUNT_INVALID:
|
||||||
|
return false;
|
||||||
|
case ADResponseCodes::ACCOUNT_CREDENTIALS_INVALID:
|
||||||
|
return true;
|
||||||
|
case ADResponseCodes::ACCOUNT_RESTRICTIONS:
|
||||||
|
return true;
|
||||||
|
case ADResponseCodes::ACCOUNT_RESTRICTIONS_TIME:
|
||||||
|
return true;
|
||||||
|
case ADResponseCodes::ACCOUNT_RESTRICTIONS_DEVICE:
|
||||||
|
return true;
|
||||||
|
case ADResponseCodes::ACCOUNT_PASSWORD_EXPIRED:
|
||||||
|
return true;
|
||||||
|
case ADResponseCodes::ACCOUNT_DISABLED:
|
||||||
|
return true;
|
||||||
|
case ADResponseCodes::ACCOUNT_CONTEXT_IDS:
|
||||||
|
return true;
|
||||||
|
case ADResponseCodes::ACCOUNT_EXPIRED:
|
||||||
|
return false;
|
||||||
|
case ADResponseCodes::ACCOUNT_PASSWORD_MUST_CHANGE:
|
||||||
|
return true;
|
||||||
|
case ADResponseCodes::ACCOUNT_LOCKED:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 2-factor authentication //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a user has TOTP setup
|
||||||
|
* @global $database $database
|
||||||
|
* @param string $username
|
||||||
|
* @return boolean true if TOTP secret exists, else false
|
||||||
|
*/
|
||||||
|
function userHasTOTP($username) {
|
||||||
|
global $database;
|
||||||
|
$secret = $database->select('accounts', 'authsecret', ['username' => $username])[0];
|
||||||
|
if (is_empty($secret)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a TOTP secret for the given user.
|
||||||
|
* @param string $username
|
||||||
|
* @return string OTP provisioning URI (for generating a QR code)
|
||||||
|
*/
|
||||||
|
function newTOTP($username) {
|
||||||
|
global $database;
|
||||||
|
$secret = random_bytes(20);
|
||||||
|
$encoded_secret = Base32::encode($secret);
|
||||||
|
$userdata = $database->select('accounts', ['email', 'authsecret', 'realname'], ['username' => $username])[0];
|
||||||
|
$totp = new TOTP((is_null($userdata['email']) ? $userdata['realname'] : $userdata['email']), $encoded_secret);
|
||||||
|
$totp->setIssuer(SYSTEM_NAME);
|
||||||
|
return $totp->getProvisioningUri();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save a TOTP secret for the user.
|
||||||
|
* @global $database $database
|
||||||
|
* @param string $username
|
||||||
|
* @param string $secret
|
||||||
|
*/
|
||||||
|
function saveTOTP($username, $secret) {
|
||||||
|
global $database;
|
||||||
|
$database->update('accounts', ['authsecret' => $secret], ['username' => $username]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify a TOTP multiauth code
|
||||||
|
* @global $database
|
||||||
|
* @param string $username
|
||||||
|
* @param int $code
|
||||||
|
* @return boolean true if it's legit, else false
|
||||||
|
*/
|
||||||
|
function verifyTOTP($username, $code) {
|
||||||
|
global $database;
|
||||||
|
$userdata = $database->select('accounts', ['email', 'authsecret'], ['username' => $username])[0];
|
||||||
|
if (is_empty($userdata['authsecret'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$totp = new TOTP(null, $userdata['authsecret']);
|
||||||
|
return $totp->verify($code);
|
||||||
|
}
|
522
lib/worst_passwords.php
Normal file
522
lib/worst_passwords.php
Normal file
@ -0,0 +1,522 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* 500 most common passwords, to be used in stopping idiots from having really bad passwords.
|
||||||
|
* Source: https://github.com/danielmiessler/SecLists/blob/master/Passwords/500-worst-passwords.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks a given password against the list of the 500 most common passwords.
|
||||||
|
* @param string $search the password to check
|
||||||
|
* @return false if not found, the password ranking if found
|
||||||
|
*/
|
||||||
|
function checkWorst500List($search) {
|
||||||
|
$worst_password_list = [
|
||||||
|
"123456",
|
||||||
|
"password",
|
||||||
|
"12345678",
|
||||||
|
"1234",
|
||||||
|
"pussy",
|
||||||
|
"12345",
|
||||||
|
"dragon",
|
||||||
|
"qwerty",
|
||||||
|
"696969",
|
||||||
|
"mustang",
|
||||||
|
"letmein",
|
||||||
|
"baseball",
|
||||||
|
"master",
|
||||||
|
"michael",
|
||||||
|
"football",
|
||||||
|
"shadow",
|
||||||
|
"monkey",
|
||||||
|
"abc123",
|
||||||
|
"pass",
|
||||||
|
"fuckme",
|
||||||
|
"6969",
|
||||||
|
"jordan",
|
||||||
|
"harley",
|
||||||
|
"ranger",
|
||||||
|
"iwantu",
|
||||||
|
"jennifer",
|
||||||
|
"hunter",
|
||||||
|
"fuck",
|
||||||
|
"2000",
|
||||||
|
"test",
|
||||||
|
"batman",
|
||||||
|
"trustno1",
|
||||||
|
"thomas",
|
||||||
|
"tigger",
|
||||||
|
"robert",
|
||||||
|
"access",
|
||||||
|
"love",
|
||||||
|
"buster",
|
||||||
|
"1234567",
|
||||||
|
"soccer",
|
||||||
|
"hockey",
|
||||||
|
"killer",
|
||||||
|
"george",
|
||||||
|
"sexy",
|
||||||
|
"andrew",
|
||||||
|
"charlie",
|
||||||
|
"superman",
|
||||||
|
"asshole",
|
||||||
|
"fuckyou",
|
||||||
|
"dallas",
|
||||||
|
"jessica",
|
||||||
|
"panties",
|
||||||
|
"pepper",
|
||||||
|
"1111",
|
||||||
|
"austin",
|
||||||
|
"william",
|
||||||
|
"daniel",
|
||||||
|
"golfer",
|
||||||
|
"summer",
|
||||||
|
"heather",
|
||||||
|
"hammer",
|
||||||
|
"yankees",
|
||||||
|
"joshua",
|
||||||
|
"maggie",
|
||||||
|
"biteme",
|
||||||
|
"enter",
|
||||||
|
"ashley",
|
||||||
|
"thunder",
|
||||||
|
"cowboy",
|
||||||
|
"silver",
|
||||||
|
"richard",
|
||||||
|
"fucker",
|
||||||
|
"orange",
|
||||||
|
"merlin",
|
||||||
|
"michelle",
|
||||||
|
"corvette",
|
||||||
|
"bigdog",
|
||||||
|
"cheese",
|
||||||
|
"matthew",
|
||||||
|
"121212",
|
||||||
|
"patrick",
|
||||||
|
"martin",
|
||||||
|
"freedom",
|
||||||
|
"ginger",
|
||||||
|
"blowjob",
|
||||||
|
"nicole",
|
||||||
|
"sparky",
|
||||||
|
"yellow",
|
||||||
|
"camaro",
|
||||||
|
"secret",
|
||||||
|
"dick",
|
||||||
|
"falcon",
|
||||||
|
"taylor",
|
||||||
|
"111111",
|
||||||
|
"131313",
|
||||||
|
"123123",
|
||||||
|
"bitch",
|
||||||
|
"hello",
|
||||||
|
"scooter",
|
||||||
|
"please",
|
||||||
|
"porsche",
|
||||||
|
"guitar",
|
||||||
|
"chelsea",
|
||||||
|
"black",
|
||||||
|
"diamond",
|
||||||
|
"nascar",
|
||||||
|
"jackson",
|
||||||
|
"cameron",
|
||||||
|
"654321",
|
||||||
|
"computer",
|
||||||
|
"amanda",
|
||||||
|
"wizard",
|
||||||
|
"xxxxxxxx",
|
||||||
|
"money",
|
||||||
|
"phoenix",
|
||||||
|
"mickey",
|
||||||
|
"bailey",
|
||||||
|
"knight",
|
||||||
|
"iceman",
|
||||||
|
"tigers",
|
||||||
|
"purple",
|
||||||
|
"andrea",
|
||||||
|
"horny",
|
||||||
|
"dakota",
|
||||||
|
"aaaaaa",
|
||||||
|
"player",
|
||||||
|
"sunshine",
|
||||||
|
"morgan",
|
||||||
|
"starwars",
|
||||||
|
"boomer",
|
||||||
|
"cowboys",
|
||||||
|
"edward",
|
||||||
|
"charles",
|
||||||
|
"girls",
|
||||||
|
"booboo",
|
||||||
|
"coffee",
|
||||||
|
"xxxxxx",
|
||||||
|
"bulldog",
|
||||||
|
"ncc1701",
|
||||||
|
"rabbit",
|
||||||
|
"peanut",
|
||||||
|
"john",
|
||||||
|
"johnny",
|
||||||
|
"gandalf",
|
||||||
|
"spanky",
|
||||||
|
"winter",
|
||||||
|
"brandy",
|
||||||
|
"compaq",
|
||||||
|
"carlos",
|
||||||
|
"tennis",
|
||||||
|
"james",
|
||||||
|
"mike",
|
||||||
|
"brandon",
|
||||||
|
"fender",
|
||||||
|
"anthony",
|
||||||
|
"blowme",
|
||||||
|
"ferrari",
|
||||||
|
"cookie",
|
||||||
|
"chicken",
|
||||||
|
"maverick",
|
||||||
|
"chicago",
|
||||||
|
"joseph",
|
||||||
|
"diablo",
|
||||||
|
"sexsex",
|
||||||
|
"hardcore",
|
||||||
|
"666666",
|
||||||
|
"willie",
|
||||||
|
"welcome",
|
||||||
|
"chris",
|
||||||
|
"panther",
|
||||||
|
"yamaha",
|
||||||
|
"justin",
|
||||||
|
"banana",
|
||||||
|
"driver",
|
||||||
|
"marine",
|
||||||
|
"angels",
|
||||||
|
"fishing",
|
||||||
|
"david",
|
||||||
|
"maddog",
|
||||||
|
"hooters",
|
||||||
|
"wilson",
|
||||||
|
"butthead",
|
||||||
|
"dennis",
|
||||||
|
"fucking",
|
||||||
|
"captain",
|
||||||
|
"bigdick",
|
||||||
|
"chester",
|
||||||
|
"smokey",
|
||||||
|
"xavier",
|
||||||
|
"steven",
|
||||||
|
"viking",
|
||||||
|
"snoopy",
|
||||||
|
"blue",
|
||||||
|
"eagles",
|
||||||
|
"winner",
|
||||||
|
"samantha",
|
||||||
|
"house",
|
||||||
|
"miller",
|
||||||
|
"flower",
|
||||||
|
"jack",
|
||||||
|
"firebird",
|
||||||
|
"butter",
|
||||||
|
"united",
|
||||||
|
"turtle",
|
||||||
|
"steelers",
|
||||||
|
"tiffany",
|
||||||
|
"zxcvbn",
|
||||||
|
"tomcat",
|
||||||
|
"golf",
|
||||||
|
"bond007",
|
||||||
|
"bear",
|
||||||
|
"tiger",
|
||||||
|
"doctor",
|
||||||
|
"gateway",
|
||||||
|
"gators",
|
||||||
|
"angel",
|
||||||
|
"junior",
|
||||||
|
"thx1138",
|
||||||
|
"porno",
|
||||||
|
"badboy",
|
||||||
|
"debbie",
|
||||||
|
"spider",
|
||||||
|
"melissa",
|
||||||
|
"booger",
|
||||||
|
"1212",
|
||||||
|
"flyers",
|
||||||
|
"fish",
|
||||||
|
"porn",
|
||||||
|
"matrix",
|
||||||
|
"teens",
|
||||||
|
"scooby",
|
||||||
|
"jason",
|
||||||
|
"walter",
|
||||||
|
"cumshot",
|
||||||
|
"boston",
|
||||||
|
"braves",
|
||||||
|
"yankee",
|
||||||
|
"lover",
|
||||||
|
"barney",
|
||||||
|
"victor",
|
||||||
|
"tucker",
|
||||||
|
"princess",
|
||||||
|
"mercedes",
|
||||||
|
"5150",
|
||||||
|
"doggie",
|
||||||
|
"zzzzzz",
|
||||||
|
"gunner",
|
||||||
|
"horney",
|
||||||
|
"bubba",
|
||||||
|
"2112",
|
||||||
|
"fred",
|
||||||
|
"johnson",
|
||||||
|
"xxxxx",
|
||||||
|
"tits",
|
||||||
|
"member",
|
||||||
|
"boobs",
|
||||||
|
"donald",
|
||||||
|
"bigdaddy",
|
||||||
|
"bronco",
|
||||||
|
"penis",
|
||||||
|
"voyager",
|
||||||
|
"rangers",
|
||||||
|
"birdie",
|
||||||
|
"trouble",
|
||||||
|
"white",
|
||||||
|
"topgun",
|
||||||
|
"bigtits",
|
||||||
|
"bitches",
|
||||||
|
"green",
|
||||||
|
"super",
|
||||||
|
"qazwsx",
|
||||||
|
"magic",
|
||||||
|
"lakers",
|
||||||
|
"rachel",
|
||||||
|
"slayer",
|
||||||
|
"scott",
|
||||||
|
"2222",
|
||||||
|
"asdf",
|
||||||
|
"video",
|
||||||
|
"london",
|
||||||
|
"7777",
|
||||||
|
"marlboro",
|
||||||
|
"srinivas",
|
||||||
|
"internet",
|
||||||
|
"action",
|
||||||
|
"carter",
|
||||||
|
"jasper",
|
||||||
|
"monster",
|
||||||
|
"teresa",
|
||||||
|
"jeremy",
|
||||||
|
"11111111",
|
||||||
|
"bill",
|
||||||
|
"crystal",
|
||||||
|
"peter",
|
||||||
|
"pussies",
|
||||||
|
"cock",
|
||||||
|
"beer",
|
||||||
|
"rocket",
|
||||||
|
"theman",
|
||||||
|
"oliver",
|
||||||
|
"prince",
|
||||||
|
"beach",
|
||||||
|
"amateur",
|
||||||
|
"7777777",
|
||||||
|
"muffin",
|
||||||
|
"redsox",
|
||||||
|
"star",
|
||||||
|
"testing",
|
||||||
|
"shannon",
|
||||||
|
"murphy",
|
||||||
|
"frank",
|
||||||
|
"hannah",
|
||||||
|
"dave",
|
||||||
|
"eagle1",
|
||||||
|
"11111",
|
||||||
|
"mother",
|
||||||
|
"nathan",
|
||||||
|
"raiders",
|
||||||
|
"steve",
|
||||||
|
"forever",
|
||||||
|
"angela",
|
||||||
|
"viper",
|
||||||
|
"ou812",
|
||||||
|
"jake",
|
||||||
|
"lovers",
|
||||||
|
"suckit",
|
||||||
|
"gregory",
|
||||||
|
"buddy",
|
||||||
|
"whatever",
|
||||||
|
"young",
|
||||||
|
"nicholas",
|
||||||
|
"lucky",
|
||||||
|
"helpme",
|
||||||
|
"jackie",
|
||||||
|
"monica",
|
||||||
|
"midnight",
|
||||||
|
"college",
|
||||||
|
"baby",
|
||||||
|
"cunt",
|
||||||
|
"brian",
|
||||||
|
"mark",
|
||||||
|
"startrek",
|
||||||
|
"sierra",
|
||||||
|
"leather",
|
||||||
|
"232323",
|
||||||
|
"4444",
|
||||||
|
"beavis",
|
||||||
|
"bigcock",
|
||||||
|
"happy",
|
||||||
|
"sophie",
|
||||||
|
"ladies",
|
||||||
|
"naughty",
|
||||||
|
"giants",
|
||||||
|
"booty",
|
||||||
|
"blonde",
|
||||||
|
"fucked",
|
||||||
|
"golden",
|
||||||
|
"0",
|
||||||
|
"fire",
|
||||||
|
"sandra",
|
||||||
|
"pookie",
|
||||||
|
"packers",
|
||||||
|
"einstein",
|
||||||
|
"dolphins",
|
||||||
|
"chevy",
|
||||||
|
"winston",
|
||||||
|
"warrior",
|
||||||
|
"sammy",
|
||||||
|
"slut",
|
||||||
|
"8675309",
|
||||||
|
"zxcvbnm",
|
||||||
|
"nipples",
|
||||||
|
"power",
|
||||||
|
"victoria",
|
||||||
|
"asdfgh",
|
||||||
|
"vagina",
|
||||||
|
"toyota",
|
||||||
|
"travis",
|
||||||
|
"hotdog",
|
||||||
|
"paris",
|
||||||
|
"rock",
|
||||||
|
"xxxx",
|
||||||
|
"extreme",
|
||||||
|
"redskins",
|
||||||
|
"erotic",
|
||||||
|
"dirty",
|
||||||
|
"ford",
|
||||||
|
"freddy",
|
||||||
|
"arsenal",
|
||||||
|
"access14",
|
||||||
|
"wolf",
|
||||||
|
"nipple",
|
||||||
|
"iloveyou",
|
||||||
|
"alex",
|
||||||
|
"florida",
|
||||||
|
"eric",
|
||||||
|
"legend",
|
||||||
|
"movie",
|
||||||
|
"success",
|
||||||
|
"rosebud",
|
||||||
|
"jaguar",
|
||||||
|
"great",
|
||||||
|
"cool",
|
||||||
|
"cooper",
|
||||||
|
"1313",
|
||||||
|
"scorpio",
|
||||||
|
"mountain",
|
||||||
|
"madison",
|
||||||
|
"987654",
|
||||||
|
"brazil",
|
||||||
|
"lauren",
|
||||||
|
"japan",
|
||||||
|
"naked",
|
||||||
|
"squirt",
|
||||||
|
"stars",
|
||||||
|
"apple",
|
||||||
|
"alexis",
|
||||||
|
"aaaa",
|
||||||
|
"bonnie",
|
||||||
|
"peaches",
|
||||||
|
"jasmine",
|
||||||
|
"kevin",
|
||||||
|
"matt",
|
||||||
|
"qwertyui",
|
||||||
|
"danielle",
|
||||||
|
"beaver",
|
||||||
|
"4321",
|
||||||
|
"4128",
|
||||||
|
"runner",
|
||||||
|
"swimming",
|
||||||
|
"dolphin",
|
||||||
|
"gordon",
|
||||||
|
"casper",
|
||||||
|
"stupid",
|
||||||
|
"shit",
|
||||||
|
"saturn",
|
||||||
|
"gemini",
|
||||||
|
"apples",
|
||||||
|
"august",
|
||||||
|
"3333",
|
||||||
|
"canada",
|
||||||
|
"blazer",
|
||||||
|
"cumming",
|
||||||
|
"hunting",
|
||||||
|
"kitty",
|
||||||
|
"rainbow",
|
||||||
|
"112233",
|
||||||
|
"arthur",
|
||||||
|
"cream",
|
||||||
|
"calvin",
|
||||||
|
"shaved",
|
||||||
|
"surfer",
|
||||||
|
"samson",
|
||||||
|
"kelly",
|
||||||
|
"paul",
|
||||||
|
"mine",
|
||||||
|
"king",
|
||||||
|
"racing",
|
||||||
|
"5555",
|
||||||
|
"eagle",
|
||||||
|
"hentai",
|
||||||
|
"newyork",
|
||||||
|
"little",
|
||||||
|
"redwings",
|
||||||
|
"smith",
|
||||||
|
"sticky",
|
||||||
|
"cocacola",
|
||||||
|
"animal",
|
||||||
|
"broncos",
|
||||||
|
"private",
|
||||||
|
"skippy",
|
||||||
|
"marvin",
|
||||||
|
"blondes",
|
||||||
|
"enjoy",
|
||||||
|
"girl",
|
||||||
|
"apollo",
|
||||||
|
"parker",
|
||||||
|
"qwert",
|
||||||
|
"time",
|
||||||
|
"sydney",
|
||||||
|
"women",
|
||||||
|
"voodoo",
|
||||||
|
"magnum",
|
||||||
|
"juice",
|
||||||
|
"abgrtyu",
|
||||||
|
"777777",
|
||||||
|
"dreams",
|
||||||
|
"maxwell",
|
||||||
|
"music",
|
||||||
|
"rush2112",
|
||||||
|
"russia",
|
||||||
|
"scorpion",
|
||||||
|
"rebecca",
|
||||||
|
"tester",
|
||||||
|
"mistress",
|
||||||
|
"phantom",
|
||||||
|
"billy",
|
||||||
|
"6666",
|
||||||
|
"albert"
|
||||||
|
];
|
||||||
|
|
||||||
|
$index = array_search($search, $worst_password_list);
|
||||||
|
if ($index === FALSE) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return $index + 1;
|
||||||
|
}
|
||||||
|
}
|
8
nbproject/project.properties
Normal file
8
nbproject/project.properties
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
auxiliary.org-netbeans-modules-html-editor-lib.default-html-public-id=-//W3C//DTD HTML 4.01 Transitional//EN
|
||||||
|
include.path=${php.global.include.path}
|
||||||
|
php.version=PHP_70
|
||||||
|
source.encoding=UTF-8
|
||||||
|
src.dir=.
|
||||||
|
tags.asp=false
|
||||||
|
tags.short=false
|
||||||
|
web.root=.
|
9
nbproject/project.xml
Normal file
9
nbproject/project.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||||
|
<type>org.netbeans.modules.php.project</type>
|
||||||
|
<configuration>
|
||||||
|
<data xmlns="http://www.netbeans.org/ns/php-project/1">
|
||||||
|
<name>WebAppTemplate</name>
|
||||||
|
</data>
|
||||||
|
</configuration>
|
||||||
|
</project>
|
11
pages.php
Normal file
11
pages.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// List of pages and metadata
|
||||||
|
define("PAGES", [
|
||||||
|
"home" => [
|
||||||
|
"title" => "home"
|
||||||
|
],
|
||||||
|
"404" => [
|
||||||
|
"title" => "404 error"
|
||||||
|
]
|
||||||
|
]);
|
5
pages/404.php
Normal file
5
pages/404.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 col-sm-offset-3 col-md-offset-4 col-lg-offset-4">
|
||||||
|
<div class="alert alert-warning"><b><?php lang("404 error");?></b><br /> <?php lang("page not found"); ?></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
1
pages/home.php
Normal file
1
pages/home.php
Normal file
@ -0,0 +1 @@
|
|||||||
|
<h1>Hello World</h1>
|
226
required.php
Normal file
226
required.php
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file contains global settings and utility functions.
|
||||||
|
*/
|
||||||
|
ob_start(); // allow sending headers after content
|
||||||
|
// Unicode, solves almost all stupid encoding problems
|
||||||
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
|
|
||||||
|
// l33t $ecurity h4x
|
||||||
|
header('X-Content-Type-Options: nosniff');
|
||||||
|
header('X-XSS-Protection: 1; mode=block');
|
||||||
|
header('X-Powered-By: Late-night coding frenzies (plz send caffeine, thx)');
|
||||||
|
$session_length = 60 * 60; // 1 hour
|
||||||
|
session_set_cookie_params($session_length, "/", null, false, true);
|
||||||
|
|
||||||
|
session_start(); // stick some cookies in it
|
||||||
|
//
|
||||||
|
// Composer
|
||||||
|
require __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
// Settings file
|
||||||
|
require __DIR__ . '/settings.php';
|
||||||
|
// List of alert messages
|
||||||
|
require __DIR__ . '/lang/messages.php';
|
||||||
|
// text strings (i18n)
|
||||||
|
require __DIR__ . '/lang/' . LANGUAGE . ".php";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kill off the running process and spit out an error message
|
||||||
|
* @param string $error error message
|
||||||
|
*/
|
||||||
|
function sendError($error) {
|
||||||
|
die("<!DOCTYPE html><html><head><title>Error</title></head><body><h1 style='color: red; font-family: sans-serif; font-size:100%;'>" . htmlspecialchars($error) . "</h1></body></html>");
|
||||||
|
}
|
||||||
|
|
||||||
|
date_default_timezone_set(TIMEZONE);
|
||||||
|
|
||||||
|
// Database settings
|
||||||
|
// Also inits database and stuff
|
||||||
|
use Medoo\Medoo;
|
||||||
|
|
||||||
|
$database;
|
||||||
|
try {
|
||||||
|
$database = new Medoo([
|
||||||
|
'database_type' => DB_TYPE,
|
||||||
|
'database_name' => DB_NAME,
|
||||||
|
'server' => DB_SERVER,
|
||||||
|
'username' => DB_USER,
|
||||||
|
'password' => DB_PASS,
|
||||||
|
'charset' => DB_CHARSET
|
||||||
|
]);
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
//header('HTTP/1.1 500 Internal Server Error');
|
||||||
|
sendError("Database error. Try again later. $ex");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!DEBUG) {
|
||||||
|
error_reporting(0);
|
||||||
|
} else {
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
ini_set('display_errors', 'On');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$VARS;
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$VARS = $_POST;
|
||||||
|
define("GET", false);
|
||||||
|
} else {
|
||||||
|
$VARS = $_GET;
|
||||||
|
define("GET", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a string or whatever is empty.
|
||||||
|
* @param $str The thingy to check
|
||||||
|
* @return boolean True if it's empty or whatever.
|
||||||
|
*/
|
||||||
|
function is_empty($str) {
|
||||||
|
return (is_null($str) || !isset($str) || $str == '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I18N string getter. If the key doesn't exist, outputs the key itself.
|
||||||
|
* @param string $key I18N string key
|
||||||
|
* @param boolean $echo whether to echo the result or return it (default echo)
|
||||||
|
*/
|
||||||
|
function lang($key, $echo = true) {
|
||||||
|
if (array_key_exists($key, STRINGS)) {
|
||||||
|
$str = STRINGS[$key];
|
||||||
|
} else {
|
||||||
|
$str = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($echo) {
|
||||||
|
echo $str;
|
||||||
|
} else {
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I18N string getter (with builder). If the key doesn't exist, outputs the key itself.
|
||||||
|
* @param string $key I18N string key
|
||||||
|
* @param array $replace key-value array of replacements.
|
||||||
|
* If the string value is "hello {abc}" and you give ["abc" => "123"], the
|
||||||
|
* result will be "hello 123".
|
||||||
|
* @param boolean $echo whether to echo the result or return it (default echo)
|
||||||
|
*/
|
||||||
|
function lang2($key, $replace, $echo = true) {
|
||||||
|
if (array_key_exists($key, STRINGS)) {
|
||||||
|
$str = STRINGS[$key];
|
||||||
|
} else {
|
||||||
|
$str = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($replace as $find => $repl) {
|
||||||
|
$str = str_replace("{" . $find . "}", $repl, $str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($echo) {
|
||||||
|
echo $str;
|
||||||
|
} else {
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if an email address is valid.
|
||||||
|
* @param string $email Email to check
|
||||||
|
* @return boolean True if email passes validation, else false.
|
||||||
|
*/
|
||||||
|
function isValidEmail($email) {
|
||||||
|
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hashes the given plaintext password
|
||||||
|
* @param String $password
|
||||||
|
* @return String the hash, using bcrypt
|
||||||
|
*/
|
||||||
|
function encryptPassword($password) {
|
||||||
|
return password_hash($password, PASSWORD_BCRYPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Securely verify a password and its hash
|
||||||
|
* @param String $password
|
||||||
|
* @param String $hash the hash to compare to
|
||||||
|
* @return boolean True if password OK, else false
|
||||||
|
*/
|
||||||
|
function comparePassword($password, $hash) {
|
||||||
|
return password_verify($password, $hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dieifnotloggedin() {
|
||||||
|
if ($_SESSION['loggedin'] != true) {
|
||||||
|
sendError("Session expired. Please log out and log in again.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the previous database action had a problem.
|
||||||
|
* @param array $specials int=>string array with special response messages for SQL errors
|
||||||
|
*/
|
||||||
|
function checkDBError($specials = []) {
|
||||||
|
global $database;
|
||||||
|
$errors = $database->error();
|
||||||
|
if (!is_null($errors[1])) {
|
||||||
|
foreach ($specials as $code => $text) {
|
||||||
|
if ($errors[1] == $code) {
|
||||||
|
sendError($text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendError("A database error occurred:<br /><code>" . $errors[2] . "</code>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* http://stackoverflow.com/a/20075147/2534036
|
||||||
|
*/
|
||||||
|
if (!function_exists('base_url')) {
|
||||||
|
|
||||||
|
function base_url($atRoot = FALSE, $atCore = FALSE, $parse = FALSE) {
|
||||||
|
if (isset($_SERVER['HTTP_HOST'])) {
|
||||||
|
$http = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';
|
||||||
|
$hostname = $_SERVER['HTTP_HOST'];
|
||||||
|
$dir = str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
|
||||||
|
|
||||||
|
$core = preg_split('@/@', str_replace($_SERVER['DOCUMENT_ROOT'], '', realpath(dirname(__FILE__))), NULL, PREG_SPLIT_NO_EMPTY);
|
||||||
|
$core = $core[0];
|
||||||
|
|
||||||
|
$tmplt = $atRoot ? ($atCore ? "%s://%s/%s/" : "%s://%s/") : ($atCore ? "%s://%s/%s/" : "%s://%s%s");
|
||||||
|
$end = $atRoot ? ($atCore ? $core : $hostname) : ($atCore ? $core : $dir);
|
||||||
|
$base_url = sprintf($tmplt, $http, $hostname, $end);
|
||||||
|
} else
|
||||||
|
$base_url = 'http://localhost/';
|
||||||
|
|
||||||
|
if ($parse) {
|
||||||
|
$base_url = parse_url($base_url);
|
||||||
|
if (isset($base_url['path']))
|
||||||
|
if ($base_url['path'] == '/')
|
||||||
|
$base_url['path'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $base_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function redirectToPageId($id, $args, $dontdie) {
|
||||||
|
header('Location: ' . URL . '?id=' . $id . $args);
|
||||||
|
if (is_null($dontdie)) {
|
||||||
|
die("Please go to " . URL . '?id=' . $id . $args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function redirectIfNotLoggedIn() {
|
||||||
|
if ($_SESSION['loggedin'] !== TRUE) {
|
||||||
|
header('Location: ' . URL . '/login.php');
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
47
settings.template.php
Normal file
47
settings.template.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Whether to show debugging data in output.
|
||||||
|
// DO NOT SET TO TRUE IN PRODUCTION!!!
|
||||||
|
define("DEBUG", false);
|
||||||
|
|
||||||
|
// Database connection settings
|
||||||
|
// See http://medoo.in/api/new for info
|
||||||
|
define("DB_TYPE", "mysql");
|
||||||
|
define("DB_NAME", "app");
|
||||||
|
define("DB_SERVER", "localhost");
|
||||||
|
define("DB_USER", "app");
|
||||||
|
define("DB_PASS", "");
|
||||||
|
define("DB_CHARSET", "utf8");
|
||||||
|
|
||||||
|
define("SITE_TITLE", "Web App Template");
|
||||||
|
|
||||||
|
// Used to identify the system in OTP and other places
|
||||||
|
define("SYSTEM_NAME", "Web App Template");
|
||||||
|
|
||||||
|
// For supported values, see http://php.net/manual/en/timezones.php
|
||||||
|
define("TIMEZONE", "America/Denver");
|
||||||
|
|
||||||
|
// Base URL for site links.
|
||||||
|
define('URL', 'http://localhost:8000/');
|
||||||
|
|
||||||
|
// See lang folder for language options
|
||||||
|
define('LANGUAGE', "en_us");
|
||||||
|
|
||||||
|
// Minimum length for new passwords
|
||||||
|
// The system checks new passwords against the 500 worst passwords and rejects
|
||||||
|
// any matches.
|
||||||
|
// If you want to have additional password requirements, go edit action.php.
|
||||||
|
// However, all that does is encourage people to use the infamous
|
||||||
|
// "post-it password manager". See also https://xkcd.com/936/ and
|
||||||
|
// http://stackoverflow.com/a/34166252/2534036 for reasons why forcing passwords
|
||||||
|
// like CaPs45$% is not actually a great idea.
|
||||||
|
// Encourage users to use 2-factor auth whenever possible.
|
||||||
|
define("MIN_PASSWORD_LENGTH", 8);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
// /!\ Warning: Changing these values may /!\ //
|
||||||
|
// /!\ violate the terms of your license agreement! /!\ //
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
define("LICENSE_TEXT", "<b>Free Software: MIT License</b>");
|
||||||
|
define("COPYRIGHT_NAME", "Netsyms Technologies");
|
||||||
|
//////////////////////////////////////////////////////////////
|
13
static/css/app.css
Normal file
13
static/css/app.css
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.banner-image {
|
||||||
|
max-height: 100px;
|
||||||
|
margin: 2em auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-brand {
|
||||||
|
font-size: 110%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
margin-top: 10em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
11
static/css/bootstrap.min.css
vendored
Normal file
11
static/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2337
static/css/font-awesome.css
vendored
Normal file
2337
static/css/font-awesome.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4
static/css/font-awesome.min.css
vendored
Normal file
4
static/css/font-awesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
static/fonts/FontAwesome.otf
Normal file
BIN
static/fonts/FontAwesome.otf
Normal file
Binary file not shown.
BIN
static/fonts/fontawesome-webfont.eot
Normal file
BIN
static/fonts/fontawesome-webfont.eot
Normal file
Binary file not shown.
2671
static/fonts/fontawesome-webfont.svg
Normal file
2671
static/fonts/fontawesome-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 434 KiB |
BIN
static/fonts/fontawesome-webfont.ttf
Normal file
BIN
static/fonts/fontawesome-webfont.ttf
Normal file
Binary file not shown.
BIN
static/fonts/fontawesome-webfont.woff
Normal file
BIN
static/fonts/fontawesome-webfont.woff
Normal file
Binary file not shown.
BIN
static/fonts/fontawesome-webfont.woff2
Normal file
BIN
static/fonts/fontawesome-webfont.woff2
Normal file
Binary file not shown.
7
static/js/app.js
Normal file
7
static/js/app.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
/* Fade out alerts */
|
||||||
|
$(".alert .close").click(function (e) {
|
||||||
|
$(this).parent().fadeOut('slow');
|
||||||
|
});
|
||||||
|
});
|
7
static/js/bootstrap.min.js
vendored
Normal file
7
static/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
static/js/jquery-3.2.1.min.js
vendored
Normal file
4
static/js/jquery-3.2.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user