Commit eb34b9aa authored by Martin Gregor's avatar Martin Gregor
Browse files

Initial commit

parents
log/*
temp/*
vendor/*
!vendor/others
*.iml
.idea/
.sass-cache/
.DS_Store
!.gitignore
!.htaccess
!web.config
app/config/config.local.neon
Order Allow,Deny
Deny from all
<?php
// Load Nette Framework or autoloader generated by Composer
require __DIR__ . '/../vendor/autoload.php';
$configurator = new Nette\Config\Configurator;
// Enable Nette Debugger for error visualisation & logging
//$configurator->setDebugMode(TRUE);
$configurator->enableDebugger(__DIR__ . '/../log');
// Specify folder for cache
$configurator->setTempDirectory(__DIR__ . '/../temp');
// Enable RobotLoader - this will load all classes automatically
$configurator->createRobotLoader()
->addDirectory(__DIR__)
->addDirectory(__DIR__ . '/../vendor/others')
->register();
// Create Dependency Injection container from config.neon file
$configurator->addConfig(__DIR__ . '/config/config.neon');
$configurator->addConfig(__DIR__ . '/config/config.local.neon', $configurator::NONE); // none section
$container = $configurator->createContainer();
return $container;
#
# SECURITY WARNING: it is CRITICAL that this file & directory are NOT accessible directly via a web browser!
#
# If you don't protect this directory from direct web access, anybody will be able to see your passwords.
# http://nette.org/security-warning
#
common:
parameters:
php:
date.timezone: Europe/Prague
# zlib.output_compression: yes
nette:
application:
errorPresenter: Error
database:
dsn: 'mysql:host=localhost;dbname=test'
user:
password:
session:
expiration: 14 days
services:
authenticator: Authenticator
routerFactory: RouterFactory
router: @routerFactory::createRouter
factories:
production < common:
development < common:
<?php
use Nette\Security,
Nette\Utils\Strings;
/**
* Users authenticator.
*/
class Authenticator extends Nette\Object implements Security\IAuthenticator
{
const
TABLE_NAME = 'users',
COLUMN_ID = 'id',
COLUMN_NAME = 'username',
COLUMN_PASSWORD = 'password',
COLUMN_ROLE = 'role',
PASSWORD_MAX_LENGTH = 4096;
/** @var Nette\Database\Connection */
private $database;
public function __construct(Nette\Database\Connection $database)
{
$this->database = $database;
}
/**
* Performs an authentication.
* @return Nette\Security\Identity
* @throws Nette\Security\AuthenticationException
*/
public function authenticate(array $credentials)
{
list($username, $password) = $credentials;
$row = $this->database->table(self::TABLE_NAME)->where(self::COLUMN_NAME, $username)->fetch();
if (!$row) {
throw new Security\AuthenticationException('The username is incorrect.', self::IDENTITY_NOT_FOUND);
} elseif (!self::verifyPassword($password, $row[self::COLUMN_PASSWORD])) {
throw new Security\AuthenticationException('The password is incorrect.', self::INVALID_CREDENTIAL);
}
$arr = $row->toArray();
unset($arr[self::COLUMN_PASSWORD]);
return new Nette\Security\Identity($row[self::COLUMN_ID], $row[self::COLUMN_ROLE], $arr);
}
/**
* Computes salted password hash.
* @param string
* @return string
*/
public static function hashPassword($password, $options = NULL)
{
if ($password === Strings::upper($password)) { // perhaps caps lock is on
$password = Strings::lower($password);
}
$password = substr($password, 0, self::PASSWORD_MAX_LENGTH);
$options = $options ?: implode('$', array(
'algo' => '$2a', // blowfish
'cost' => '07',
'salt' => Strings::random(22),
));
return crypt($password, $options);
}
/**
* Verifies that a password matches a hash.
* @return bool
*/
public static function verifyPassword($password, $hash)
{
return self::hashPassword($password, $hash) === $hash
|| (PHP_VERSION_ID >= 50307 && substr($hash, 0, 3) === '$2a' && self::hashPassword($password, $tmp = '$2x' . substr($hash, 3)) === $tmp);
}
}
<?php
/**
* Base presenter for all application presenters.
*/
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
}
<?php
use Nette\Diagnostics\Debugger;
/**
* Error presenter.
*/
class ErrorPresenter extends BasePresenter
{
/**
* @param Exception
* @return void
*/
public function renderDefault($exception)
{
if ($this->isAjax()) { // AJAX request? Just note this error in payload.
$this->payload->error = TRUE;
$this->terminate();
} elseif ($exception instanceof Nette\Application\BadRequestException) {
$code = $exception->getCode();
// load template 403.latte or 404.latte or ... 4xx.latte
$this->setView(in_array($code, array(403, 404, 405, 410, 500)) ? $code : '4xx');
// log to access.log
Debugger::log("HTTP code $code: {$exception->getMessage()} in {$exception->getFile()}:{$exception->getLine()}", 'access');
} else {
$this->setView('500'); // load template 500.latte
Debugger::log($exception, Debugger::ERROR); // and log exception
}
}
}
<?php
/**
* Homepage presenter.
*/
class HomepagePresenter extends BasePresenter
{
public function renderDefault()
{
$this->template->anyVariable = 'any value';
}
}
<?php
use Nette\Application\UI;
/**
* Sign in/out presenters.
*/
class SignPresenter extends BasePresenter
{
/**
* Sign-in form factory.
* @return Nette\Application\UI\Form
*/
protected function createComponentSignInForm()
{
$form = new UI\Form;
$form->addText('username', 'Username:')
->setRequired('Please enter your username.');
$form->addPassword('password', 'Password:')
->setRequired('Please enter your password.');
$form->addCheckbox('remember', 'Keep me signed in');
$form->addSubmit('send', 'Sign in');
// call method signInFormSucceeded() on success
$form->onSuccess[] = $this->signInFormSucceeded;
return $form;
}
public function signInFormSucceeded($form)
{
$values = $form->getValues();
if ($values->remember) {
$this->getUser()->setExpiration('14 days', FALSE);
} else {
$this->getUser()->setExpiration('20 minutes', TRUE);
}
try {
$this->getUser()->login($values->username, $values->password);
$this->redirect('Homepage:');
} catch (Nette\Security\AuthenticationException $e) {
$form->addError($e->getMessage());
}
}
public function actionOut()
{
$this->getUser()->logout();
$this->flashMessage('You have been signed out.');
$this->redirect('in');
}
}
<?php
use Nette\Application\Routers\RouteList,
Nette\Application\Routers\Route,
Nette\Application\Routers\SimpleRouter;
/**
* Router factory.
*/
class RouterFactory
{
/**
* @return Nette\Application\IRouter
*/
public function createRouter()
{
$router = new RouteList();
$router[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');
return $router;
}
}
{**
* My Application layout template.
*
* @param string $basePath web base path
* @param string $robots tell robots how to index the content of a page (optional)
* @param array $flashes flash messages
*}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="description" content="">
<meta name="robots" content="{$robots}" n:ifset="$robots">
<title>{block title|striptags|upper}Nette Application Skeleton{/block}</title>
<link rel="stylesheet" media="screen,projection,tv" href="{$basePath}/css/screen.css">
<link rel="stylesheet" media="print" href="{$basePath}/css/print.css">
<link rel="shortcut icon" href="{$basePath}/favicon.ico">
{block head}{/block}
</head>
<body>
<script> document.documentElement.className+=' js' </script>
<div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
{include #content}
{block scripts}
<script src="{$basePath}/js/jquery.js"></script>
<script src="{$basePath}/js/netteForms.js"></script>
<script src="{$basePath}/js/main.js"></script>
{/block}
</body>
</html>
{var $robots = noindex}
{block content}
<h1 n:block=title>Access Denied</h1>
<p>You do not have permission to view this page. Please try contact the web
site administrator if you believe you should be able to view this page.</p>
<p><small>error 403</small></p>
{var $robots = noindex}
{block content}
<h1 n:block=title>Page Not Found</h1>
<p>The page you requested could not be found. It is possible that the address is
incorrect, or that the page no longer exists. Please use a search engine to find
what you are looking for.</p>
<p><small>error 404</small></p>
{var $robots = noindex}
{block content}
<h1 n:block=title>Method Not Allowed</h1>
<p>The requested method is not allowed for the URL.</p>
<p><small>error 405</small></p>
{var $robots = noindex}
{block content}
<h1 n:block=title>Page Not Found</h1>
<p>The page you requested has been taken off the site. We apologize for the inconvenience.</p>
<p><small>error 410</small></p>
{var $robots = noindex}
{block content}
<h1 n:block=title>Oops...</h1>
<p>Your browser sent a request that this server could not understand or process.</p>
{layout none}
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="robots" content="noindex">
<style>
body { color: #333; background: white; width: 500px; margin: 100px auto }
h1 { font: bold 47px/1.5 sans-serif; margin: .6em 0 }
p { font: 21px/1.5 Georgia,serif; margin: 1.5em 0 }
small { font-size: 70%; color: gray }
</style>
<h1>Server Error</h1>
<p>We're sorry! The server encountered an internal error and
was unable to complete your request. Please try again later.</p>
<p><small>error 500</small></p>
This diff is collapsed.
{var $robots = noindex}
{block content}
<h1 n:block=title>Sign in</h1>
{control signInForm}
{* or use {include '../components/form.latte', form => signInForm} *}
{form $form}
<ul class=error n:if="$form->errors">
<li n:foreach="$form->errors as $error">{$error}</li>
</ul>
<table>
<tr n:foreach="$form->controls as $input" n:class="$input->required ? required">
<th>{if $input->controlPrototype->type !== checkbox}{label $input /}{/if}</th>
<td>{input $input} {if $input->controlPrototype->type === checkbox}{label $input /}{/if}
<span class=error n:if="$input->errors">{$input->errors|implode:' '}</span>
</td>
</tr>
</table>
{/form}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment