Compare commits

...

15 Commits

Author SHA1 Message Date
Sven Slootweg cb26bae082 Add README 11 years ago
Sven Slootweg e830661cbc Registration system and small fixes 11 years ago
Sven Slootweg 0993d7dad6 Add custom Pure CSS skin 11 years ago
Sven Slootweg d18010aab9 Add Pure CSS 11 years ago
Sven Slootweg 0df4cf89b2 Add login functionality 11 years ago
Sven Slootweg 8658d03bd8 Move login UI and add error message UI 11 years ago
Sven Slootweg 975a8c0a7d Add login UI 11 years ago
Sven Slootweg eb1fa7598e Add error and notice flashing 11 years ago
Sven Slootweg 9233094267 Add User class 11 years ago
Sven Slootweg abeaa993a4 Render all pages in the site design 11 years ago
Sven Slootweg e2a18f681b Add old site design 11 years ago
Sven Slootweg 22622d6b3c Initial routing 11 years ago
Sven Slootweg eeba3a5ef3 Add Page class 11 years ago
Sven Slootweg de7bf518f5 Add PHP Markdown library 11 years ago
Sven Slootweg 03cc99823c Actually include CPHP 11 years ago

@ -0,0 +1 @@
This will be the new site for http://cryto.net/.

@ -0,0 +1,31 @@
<?php
/*
* Cryto is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if(!isset($_APP)) { die("Unauthorized."); }
class Page extends CPHPDatabaseRecordClass
{
public $table_name = "pages";
public $fill_query = "SELECT * FROM pages WHERE `Id` = :Id";
public $verify_query = "SELECT * FROM pages WHERE `Id` = :Id";
public $prototype = array(
'string' => array(
"Title" => "Title",
"Slug" => "Slug",
),
'none' => array(
"Body" => "Body"
)
);
}

@ -0,0 +1,138 @@
<?php
/*
* Cryto is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if(!isset($_APP)) { die("Unauthorized."); }
class User extends CPHPDatabaseRecordClass
{
public $table_name = "users";
public $fill_query = "SELECT * FROM users WHERE `Id` = :Id";
public $verify_query = "SELECT * FROM users WHERE `Id` = :Id";
public $prototype = array(
'string' => array(
'Username' => "Username",
'Hash' => "Hash",
'Salt' => "Salt",
'EmailAddress' => "EmailAddress"
),
'boolean' => array(
'IsAdmin' => "Admin",
'IsBanned' => "Banned"
),
'timestamp' => array(
"RegistrationDate" => "RegistrationDate"
)
);
public function GenerateSalt()
{
$this->uSalt = random_string(10);
}
public function GenerateHash()
{
if(!empty($this->uSalt))
{
if(!empty($this->uPassword))
{
$this->uHash = $this->CreateHash($this->uPassword);
}
else
{
throw new Exception("User object is missing a password.");
}
}
else
{
throw new Exception("User object is missing a salt.");
}
}
public function CreateHash($input)
{
global $cphp_config;
$hash = crypt($input, "$5\$rounds=50000\${$this->uSalt}{$cphp_config->salt}$");
$parts = explode("$", $hash);
return $parts[4];
}
public function VerifyPassword($password)
{
if($this->CreateHash($password) == $this->sHash)
{
return true;
}
else
{
return false;
}
}
public function Authenticate()
{
$_SESSION['user_id'] = $this->sId;
$_SESSION['logout_key'] = random_string(32);
$_SESSION['is_admin'] = $this->sIsAdmin;
$this->SetGlobalVariables();
}
public function Deauthenticate()
{
unset($_SESSION['user_id']);
unset($_SESSION['is_admin']);
}
public function SetGlobalVariables()
{
NewTemplater::SetGlobalVariable("my-username", $this->sUsername);
NewTemplater::SetGlobalVariable("logout-key", $_SESSION['logout_key']);
}
public static function CheckIfUsernameExists($username)
{
try
{
$result = User::FindByUsername($username);
return true;
}
catch (NotFoundException $e)
{
return false;
}
}
public static function FindByUsername($username)
{
return self::CreateFromQuery("SELECT * FROM users WHERE `Username` = :Username", array(':Username' => $username), 0, true);
}
public static function CheckIfEmailAddressExists($username)
{
try
{
$result = User::FindByEmailAddress($username);
return true;
}
catch (NotFoundException $e)
{
return false;
}
}
public static function FindByEmailAddress($email)
{
return self::CreateFromQuery("SELECT * FROM users WHERE `EmailAddress` = :EmailAddress", array(':EmailAddress' => $email), 0, true);
}
}

@ -15,3 +15,79 @@ if(!isset($_APP)) { die("Unauthorized."); }
$_CPHP = true;
$_CPHP_CONFIG = "../config.json";
require("cphp/base.php");
require("lib/Markdown.php");
require("lib/MarkdownExtra.php");
if(!empty($_SESSION['user_id']))
{
try
{
$sCurrentUser = new User($_SESSION['user_id']);
NewTemplater::SetGlobalVariable("logged-in", true);
}
catch (NotFoundException $e)
{
NewTemplater::SetGlobalVariable("logged-in", false);
/* Pass */
}
}
else
{
NewTemplater::SetGlobalVariable("logged-in", false);
}
NewTemplater::RegisterVariableHook("errors", "get_errors");
NewTemplater::RegisterVariableHook("notices", "get_notices");
function get_errors($fetch)
{
if(isset($_SESSION['errors']))
{
$errors = $_SESSION['errors'];
if($fetch === true)
{
/* We only want to clear out errors if a call to
* actually retrieve the errors was made, not just
* something like an isempty. */
$_SESSION['errors'] = array();
}
return $errors;
}
else
{
return array();
}
}
function get_notices($fetch)
{
if(isset($_SESSION['notices']))
{
$notices = $_SESSION['notices'];
if($fetch === true)
{
$_SESSION['notices'] = array();
}
return $notices;
}
else
{
return array();
}
}
function flash_error($message)
{
$_SESSION['errors'][] = $message;
}
function flash_notice($message)
{
$_SESSION['notices'][] = $message;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,40 @@
<?php
#
# Markdown Extra - A text-to-HTML conversion tool for web writers
#
# PHP Markdown Extra
# Copyright (c) 2004-2013 Michel Fortin
# <http://michelf.com/projects/php-markdown/>
#
# Original Markdown
# Copyright (c) 2004-2006 John Gruber
# <http://daringfireball.net/projects/markdown/>
#
namespace Michelf;
# Just force Michelf/Markdown.php to load. This is needed to load
# the temporary implementation class. See below for details.
\Michelf\Markdown::MARKDOWNLIB_VERSION;
#
# Markdown Extra Parser Class
#
# Note: Currently the implementation resides in the temporary class
# \Michelf\MarkdownExtra_TmpImpl (in the same file as \Michelf\Markdown).
# This makes it easier to propagate the changes between the three different
# packaging styles of PHP Markdown. Once this issue is resolved, the
# _MarkdownExtra_TmpImpl will disappear and this one will contain the code.
#
class MarkdownExtra extends \Michelf\_MarkdownExtra_TmpImpl {
### Parser Implementation ###
# Temporarily, the implemenation is in the _MarkdownExtra_TmpImpl class.
# See note above.
}
?>

@ -0,0 +1,18 @@
<?php
/*
* Cryto is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if(!isset($_APP)) { die("Unauthorized."); }
/* TODO: Have a dynamic homepage rather than a static one. */
$sPageContents = NewTemplater::Render("homepage", $locale->strings, array());

@ -0,0 +1,49 @@
<?php
/*
* Cryto is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if(!isset($_APP)) { die("Unauthorized."); }
if(empty($_POST['username']))
{
flash_error("You did not enter a username.");
}
if(empty($_POST['password']))
{
flash_error("You did not enter a password.");
}
if(count(get_errors(false)) == 0)
{
try
{
$sUser = User::CreateFromQuery("SELECT * FROM users WHERE `Username` = :Username", array(":Username" => $_POST['username']), 30, true);
}
catch (NotFoundException $e)
{
flash_error("Invalid username.");
redirect("/");
}
if($sUser->VerifyPassword($_POST['password']))
{
$sUser->Authenticate();
}
else
{
flash_error("Invalid password.");
redirect("/");
}
}
redirect("/");

@ -0,0 +1,25 @@
<?php
/*
* Cryto is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if(!isset($_APP)) { die("Unauthorized."); }
try
{
$sPage = Page::CreateFromQuery("SELECT * FROM pages WHERE `Slug` = :Slug", array(":Slug" => $router->uParameters[1]), 60, true);
}
catch (NotFoundException $e)
{
throw new RouterException("Page does not exist.");
}
$sPageContents = Michelf\MarkdownExtra::defaultTransform($sPage->uBody);

@ -0,0 +1,72 @@
<?php
/*
* Cryto is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if(!isset($_APP)) { die("Unauthorized."); }
if($router->uMethod == "post")
{
if(empty($_POST['username']))
{
flash_error("You did not enter a username.");
}
elseif(User::CheckIfUsernameExists($_POST['username']) === true)
{
flash_error("That username is already in use.");
}
if(empty($_POST['email']))
{
flash_error("You did not enter an e-mail address.");
}
elseif(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) === false)
{
flash_error("The e-mail address you entered is invalid.");
}
elseif(User::CheckIfEmailAddressExists($_POST['email']) === true)
{
flash_error("That e-mail address is already in use.");
}
if(empty($_POST['password']))
{
flash_error("You did not enter a password.");
}
elseif(empty($_POST['password2']))
{
flash_error("You did not enter a password confirmation.");
}
elseif($_POST['password'] != $_POST['password2'])
{
flash_error("The passwords you entered do not match.");
}
if(count(get_errors(false)) == 0)
{
$sUser = new User();
$sUser->uUsername = $_POST['username'];
$sUser->uPassword = $_POST['password'];
$sUser->uEmailAddress = $_POST['email'];
$sUser->uRegistrationDate = time();
$sUser->uIsAdmin = false;
$sUser->uIsBanned = false;
$sUser->GenerateSalt();
$sUser->GenerateHash();
$sUser->InsertIntoDatabase();
$sUser->Authenticate();
redirect("/");
}
}
$sPageTitle = "Register a new account";
$sPageHeader = "Register";
$sPageContents = NewTemplater::Render("register", $locale->strings, array());

@ -14,3 +14,39 @@
$_APP = true;
require("includes/base.php");
$sPageTitle = "";
$sPageContents = "";
$sPageHeader = "";
$router = new CPHPRouter();
$router->allow_slash = true;
$router->ignore_query = true;
$router->routes = array(
0 => array(
"^/$" => "modules/homepage.php",
"^/login$" => array(
"target" => "modules/login.php",
"methods" => "post"
),
"^/register$" => "modules/register.php",
"^/(.*)$" => "modules/page.php"
)
);
try
{
$router->RouteRequest();
}
catch (RouterException $e)
{
http_status_code(404);
die("404 Not Found");
}
echo(NewTemplater::Render("layout", $locale->strings, array(
"title" => $sPageTitle,
"header" => $sPageHeader,
"contents" => $sPageContents
)));

@ -0,0 +1,908 @@
/* from YUICSS buttons-core.css */
.pure-button {
/* Structure */
display: inline-block;
*display: inline; /*IE 6/7*/
zoom: 1;
line-height: normal;
white-space: nowrap;
vertical-align: baseline;
text-align: center;
cursor: pointer;
-webkit-user-drag: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* Firefox: Get rid of the inner focus border */
.pure-button::-moz-focus-inner{
padding: 0;
border: 0;
}
/* end from YUICSS buttons-core.css */
/* from YUICSS buttons.css */
/*csslint unqualified-attributes:false*/
.pure-button {
font-size: 100%;
*font-size: 90%; /*IE 6/7 - To reduce IE's oversized button text*/
*overflow: visible; /*IE 6/7 - Because of IE's overly large left/right padding on buttons */
padding: 0.5em 1.77em 0.5em;
color: #030303; /* rgba not supported (IE 8) */
/* color: rgba(0, 0, 0, 0.80); rgba supported */
/* *color: #444; IE 6 & 7 */
border: 1px solid #9e9e9e; /*IE 6/7/8*/
border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/
background-color: #adadad;
border-radius: 2px;
text-decoration: none;
-webkit-font-smoothing: antialiased;
/* Transitions */
-webkit-transition: 0.1s linear -webkit-box-shadow;
-moz-transition: 0.1s linear -moz-box-shadow;
-ms-transition: 0.1s linear box-shadow;
-o-transition: 0.1s linear box-shadow;
transition: 0.1s linear box-shadow;
}
.pure-button-hover,
.pure-button:hover {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#00000000', GradientType=0);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(transparent), color-stop(40%, rgba(0,0,0, 0.05)), to(rgba(0,0,0, 0.05)));
background-image: -webkit-linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.15));
background-image: -moz-linear-gradient(top, rgba(0,0,0, 0.05) 0%, rgba(0,0,0, 0.05));
background-image: -ms-linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.15));
background-image: -o-linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.05));
background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.05));
}
.pure-button-active,
.pure-button:active {
box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset;
}
.pure-button[disabled],
.pure-button-disabled,
.pure-button-disabled:hover,
.pure-button-disabled:active {
border: none;
background-image: none;
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
filter: alpha(opacity=40);
-khtml-opacity: 0.40;
-moz-opacity: 0.40;
opacity: 0.40;
cursor: not-allowed;
box-shadow: none;
}
.pure-button-hidden {
display: none;
}
/* Firefox: Get rid of the inner focus border */
.pure-button::-moz-focus-inner{
padding: 0;
border: 0;
}
.pure-button-primary,
.pure-button-selected,
a.pure-button-primary,
a.pure-button-selected {
background-color: #303030;
color: #fcfcfc;
}
.pure-button:-moz-focusring {
outline-color: rgba(0, 0, 0, 0.85);
}
/*! Copyright 2013 Yahoo! Inc. http://yuilibrary.com/license/ */
/* This page lists core form styles adopted from Normalize.css. */
/*! Copyright (c) Nicolas Gallagher and Jonathan Neal */
/*! normalize.css v1.1.0 | MIT License | git.io/normalize */
/* This page has Normalize.css form-specific style rules applied to a .yui3-form context */
/* ==========
Forms Core
=========*/
/*
* Corrects margin displayed oddly in IE 6/7.
*/
.pure-skin-cryto .pure-form {
margin: 0;
}
/* Define consistent border, margin, and padding.*/
.pure-skin-cryto .pure-form fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/*
* 1. Corrects color not being inherited in IE 6/7/8/9.
* 2. Corrects text not wrapping in Firefox 3.
* 3. Corrects alignment displayed oddly in IE 6/7.
*/
.pure-skin-cryto .pure-form legend {
border: 0; /* 1 */
padding: 0;
white-space: normal; /* 2 */
*margin-left: -7px; /* 3 */
}
/*
* 1. Corrects font size not being inherited in all browsers.
* 2. Addresses margins set differently in IE 6/7, Firefox 3+, Safari 5,
* and Chrome.
* 3. Improves appearance and consistency in all browsers.
*/
.pure-skin-cryto .pure-form button,
.pure-skin-cryto .pure-form input,
.pure-skin-cryto .pure-form select,
.pure-skin-cryto .pure-form textarea {
font-size: 100%; /* 1 */
margin: 0; /* 2 */
vertical-align: baseline; /* 3 */
*vertical-align: middle; /* 3 */
}
/*
* Addresses Firefox 3+ setting `line-height` on `input` using `!important` in
* the UA stylesheet.
*/
.pure-skin-cryto .pure-form button,
.pure-skin-cryto .pure-form input {
line-height: normal;
}
/*
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Corrects inability to style clickable `input` types in iOS.
* 3. Improves usability and consistency of cursor style between image-type
* `input` and others.
* 4. Removes inner spacing in IE 7 without affecting normal text inputs.
* Known issue: inner spacing remains in IE 6.
*/
.pure-skin-cryto .pure-form button,
.pure-skin-cryto .pure-form input[type="button"], /* 1 */
.pure-skin-cryto .pure-form input[type="reset"],
.pure-skin-cryto .pure-form input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
*overflow: visible; /* 4 */
}
/*
* Re-set default cursor for disabled elements.
*/
.pure-skin-cryto .pure-form button[disabled],
.pure-skin-cryto .pure-form input[disabled] {
cursor: default;
}
/*
* 1. Addresses box sizing set to content-box in IE 8/9.
* 2. Removes excess padding in IE 8/9.
* 3. Removes excess padding in IE 7.
* Known issue: excess padding remains in IE 6.
*/
.pure-skin-cryto .pure-form input[type="checkbox"],
.pure-skin-cryto .pure-form input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
*height: 13px; /* 3 */
*width: 13px; /* 3 */
}
/*
* 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.
* 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome
* (include `-moz` to future-proof).
*/
.pure-skin-cryto .pure-form input[type="search"] {
-webkit-appearance: textfield; /* 1 */
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /* 2 */
box-sizing: content-box;
}
/*
* Removes inner padding and search cancel button in Safari 5 and Chrome
* on OS X.
*/
.pure-skin-cryto .pure-form input[type="search"]::-webkit-search-cancel-button,
.pure-skin-cryto .pure-form input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/*
* Removes inner padding and border in Firefox 3+.
*/
.pure-skin-cryto .pure-form button::-moz-focus-inner,
.pure-skin-cryto .pure-form input::-moz-focus-inner {
border: 0;
padding: 0;
}
/*
* 1. Removes default vertical scrollbar in IE 6/7/8/9.
* 2. Improves readability and alignment in all browsers.
*/
.pure-skin-cryto .pure-form textarea {
overflow: auto; /* 1 */
vertical-align: top; /* 2 */
}
/* =============== forms-responsive.css ================
=========================================================*/
@media only screen and (max-width : 480px) {
.pure-skin-cryto .pure-form button[type="submit"] {
margin: 0.7em 0 0;
}
.pure-skin-cryto .pure-form input[type="text"],
.pure-skin-cryto .pure-form input[type="password"],
.pure-skin-cryto .pure-form input[type="email"],
.pure-skin-cryto .pure-form input[type="url"],
.pure-skin-cryto .pure-form input[type="date"],
.pure-skin-cryto .pure-form input[type="month"],
.pure-skin-cryto .pure-form input[type="time"],
.pure-skin-cryto .pure-form input[type="datetime"],
.pure-skin-cryto .pure-form input[type="datetime-local"],
.pure-skin-cryto .pure-form input[type="week"],
.pure-skin-cryto .pure-form input[type="number"],
.pure-skin-cryto .pure-form input[type="search"],
.pure-skin-cryto .pure-form input[type="tel"],
.pure-skin-cryto .pure-form input[type="color"],
.pure-skin-cryto .pure-form label {
margin-bottom: 0.3em;
display: block;
}
.pure-skin-cryto .pure-group input[type="text"],
.pure-skin-cryto .pure-group input[type="password"],
.pure-skin-cryto .pure-group input[type="email"],
.pure-skin-cryto .pure-group input[type="url"],
.pure-skin-cryto .pure-group input[type="date"],
.pure-skin-cryto .pure-group input[type="month"],
.pure-skin-cryto .pure-group input[type="time"],
.pure-skin-cryto .pure-group input[type="datetime"],
.pure-skin-cryto .pure-group input[type="datetime-local"],
.pure-skin-cryto .pure-group input[type="week"],
.pure-skin-cryto .pure-group input[type="number"],
.pure-skin-cryto .pure-group input[type="search"],
.pure-skin-cryto .pure-group input[type="tel"],
.pure-skin-cryto .pure-group input[type="color"] {
margin-bottom: 0;
}
.pure-skin-cryto .pure-form-aligned .pure-control-group label {
margin-bottom: 0.3em;
text-align: left;
display: block;
width: 100%;
}
.pure-skin-cryto .pure-form-aligned .pure-controls {
margin: 1.5em 0 0 0;
}
/* NOTE: pure-help-inline is deprecated. Use .pure-form-message-inline instead. */
.pure-skin-cryto .pure-form .pure-help-inline,
.pure-skin-cryto .pure-form-message-inline,
.pure-skin-cryto .pure-form-message {
display: block;
font-size: 80%;
/* increased bottom padding to make it group with its related input element */
padding: 0.2em 0 0.8em;
}
}
/* =============== forms.css ================
=========================================================*/
.pure-skin-cryto .pure-form input[type="text"],
.pure-skin-cryto .pure-form input[type="password"],
.pure-skin-cryto .pure-form input[type="email"],
.pure-skin-cryto .pure-form input[type="url"],
.pure-skin-cryto .pure-form input[type="date"],
.pure-skin-cryto .pure-form input[type="month"],
.pure-skin-cryto .pure-form input[type="time"],
.pure-skin-cryto .pure-form input[type="datetime"],
.pure-skin-cryto .pure-form input[type="datetime-local"],
.pure-skin-cryto .pure-form input[type="week"],
.pure-skin-cryto .pure-form input[type="number"],
.pure-skin-cryto .pure-form input[type="search"],
.pure-skin-cryto .pure-form input[type="tel"],
.pure-skin-cryto .pure-form input[type="color"],
.pure-skin-cryto .pure-form select,
.pure-skin-cryto .pure-form textarea {
padding: 0.5em 0.71em;
display: inline-block;
border: 1px solid #e6e6e6;
font-size: 0.8em;
box-shadow: inset 0 1px 3px #e6e6e6;
border-radius: 4px;
-webkit-transition: 0.3s linear border;
-moz-transition: 0.3s linear border;
-ms-transition: 0.3s linear border;
-o-transition: 0.3s linear border;
transition: 0.3s linear border;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
}
.pure-skin-cryto .pure-form input[type="text"]:focus,
.pure-skin-cryto .pure-form input[type="password"]:focus,
.pure-skin-cryto .pure-form input[type="email"]:focus,
.pure-skin-cryto .pure-form input[type="url"]:focus,
.pure-skin-cryto .pure-form input[type="date"]:focus,
.pure-skin-cryto .pure-form input[type="month"]:focus,
.pure-skin-cryto .pure-form input[type="time"]:focus,
.pure-skin-cryto .pure-form input[type="datetime"]:focus,
.pure-skin-cryto .pure-form input[type="datetime-local"]:focus,
.pure-skin-cryto .pure-form input[type="week"]:focus,
.pure-skin-cryto .pure-form input[type="number"]:focus,
.pure-skin-cryto .pure-form input[type="search"]:focus,
.pure-skin-cryto .pure-form input[type="tel"]:focus,
.pure-skin-cryto .pure-form input[type="color"]:focus,
.pure-skin-cryto .pure-form select:focus,
.pure-skin-cryto .pure-form textarea:focus {
outline: 0;
outline: thin dotted \9; /* IE6-9 */
border-color: #129FEA;
}
.pure-skin-cryto .pure-form input[type="file"]:focus,
.pure-skin-cryto .pure-form input[type="radio"]:focus,
.pure-skin-cryto .pure-form input[type="checkbox"]:focus {
outline: thin dotted #333;
outline: 1px auto #129FEA;
}
.pure-skin-cryto .pure-form .pure-checkbox,
.pure-skin-cryto .pure-form .pure-radio {
margin: 0.5em 0;
display: block;
}
.pure-skin-cryto .pure-form input[type="text"][disabled],
.pure-skin-cryto .pure-form input[type="password"][disabled],
.pure-skin-cryto .pure-form input[type="email"][disabled],
.pure-skin-cryto .pure-form input[type="url"][disabled],
.pure-skin-cryto .pure-form input[type="date"][disabled],
.pure-skin-cryto .pure-form input[type="month"][disabled],
.pure-skin-cryto .pure-form input[type="time"][disabled],
.pure-skin-cryto .pure-form input[type="datetime"][disabled],
.pure-skin-cryto .pure-form input[type="datetime-local"][disabled],
.pure-skin-cryto .pure-form input[type="week"][disabled],
.pure-skin-cryto .pure-form input[type="number"][disabled],
.pure-skin-cryto .pure-form input[type="search"][disabled],
.pure-skin-cryto .pure-form input[type="tel"][disabled],
.pure-skin-cryto .pure-form input[type="color"][disabled],
.pure-skin-cryto .pure-form select[disabled],
.pure-skin-cryto .pure-form textarea[disabled],
.pure-skin-cryto .pure-form input[readonly],
.pure-skin-cryto .pure-form select[readonly],
.pure-skin-cryto .pure-form textarea[readonly] {
cursor: not-allowed;
box-shadow: inset 0 1px 10px #ededed;
background-color: #fff;
color: #757575;
border-color: #e6e6e6;
}
.pure-skin-cryto .pure-form input:focus:invalid,
.pure-skin-cryto .pure-form textarea:focus:invalid,
.pure-skin-cryto .pure-form select:focus:invalid {
color: #b94a48;
border: 1px solid #ee5f5b;
}
.pure-skin-cryto .pure-form input:focus:invalid:focus,
.pure-skin-cryto .pure-form textarea:focus:invalid:focus,
.pure-skin-cryto .pure-form select:focus:invalid:focus {
border-color: #e9322d;
}
.pure-skin-cryto .pure-form input[type="file"]:focus:invalid:focus,
.pure-skin-cryto .pure-form input[type="radio"]:focus:invalid:focus,
.pure-skin-cryto .pure-form input[type="checkbox"]:focus:invalid:focus {
outline-color: #e9322d;
}
.pure-skin-cryto .pure-form select {
border: 1px solid #e6e6e6;
background-color: white;
}
.pure-skin-cryto .pure-form select[multiple] {
height: auto;
}
.pure-skin-cryto .pure-form label {
margin: 0.5em 0 0.2em;
color: #030303;
font-size:90%;
}
.pure-skin-cryto .pure-form fieldset {
margin: 0;
padding: 0.35em 0 0.75em;
border: 0;
}
.pure-skin-cryto .pure-form legend {
display: block;
width: 100%;
padding: 0.3em 0;
margin-bottom: 0.3em;
font-size: 125%;
color: #030303;
border-bottom: 1px solid #ededed;
}
.pure-skin-cryto .pure-form-stacked label {
display: block;
}
.pure-skin-cryto .pure-form-aligned input,
.pure-skin-cryto .pure-form-aligned textarea,
.pure-skin-cryto .pure-form-aligned select,
.pure-skin-cryto .pure-form-aligned .pure-help-inline, /* note: pure-help-inline is deprecated. Use .pure-form-message-inline instead */
.pure-form-message-inline {
display: inline-block;
*display: inline; /* IE7 inline-block hack */
*zoom: 1;
vertical-align: middle;
}
/* aligned Forms */
.pure-skin-cryto .pure-form-aligned .pure-control-group {
margin-bottom: 0.5em;
}
.pure-skin-cryto .pure-form-aligned .pure-control-group label {
text-align: right;
display: inline-block;
vertical-align: middle;
width: 10em;
margin: 0 1em 0 0;
}
.pure-skin-cryto .pure-form-aligned .pure-controls {
margin: 1.5em 0 0 10em;
}
/* Rounded Inputs */
.pure-skin-cryto .pure-form .pure-input-rounded {
border-radius: 30px;
padding-left: 1em;
}
/* Grouped Inputs */
.pure-skin-cryto .pure-form .pure-group fieldset {
margin-bottom: 10px;
}
.pure-skin-cryto .pure-form .pure-group input {
display: block;
padding: 0.5em 0.71em;
margin: 0;
border-radius: 0;
position: relative;
top: -1px;
}
.pure-skin-cryto .pure-form .pure-group input:focus {
z-index: 2;
}
.pure-skin-cryto .pure-form .pure-group input:first-child {
top: 1px;
border-radius: 4px 4px 0px 0px;
}
.pure-skin-cryto .pure-form .pure-group input:last-child {
top: -2px;
border-radius: 0px 0px 4px 4px;
}
.pure-skin-cryto .pure-form .pure-group button {
margin: 0.35em 0;
}
.pure-skin-cryto .pure-form .pure-input-1 {
width: 100%;
}
.pure-skin-cryto .pure-form .pure-input-2-3 {
width: 66%;
}
.pure-skin-cryto .pure-form .pure-input-1-2 {
width: 50%;
}
.pure-skin-cryto .pure-form .pure-input-1-3 {
width: 33%;
}
.pure-skin-cryto .pure-form .pure-input-1-4 {
width: 25%;
}
/* Inline help for forms */
/* Note: pure-help-inline is deprecated. Use .pure-form-message-inline instead */
.pure-skin-cryto .pure-form .pure-help-inline,
.pure-skin-cryto .pure-form-message-inline {
display: inline-block;
padding-left: 0.3em;
color: #757575;
font-size: 90%;
vertical-align: middle;
}
/* Block help for forms */
.pure-skin-cryto .pure-form-message {
display: block;
margin: .5em 0 .2em;
color: #757575;
font-size: 90%;
}
/* foundational CSS */
.pure-skin-cryto .pure-table {
/* Remove spacing between table cells (from Normalize.css) */
border-collapse: separate;
border-spacing: 0;
empty-cells: show;
border: 1px solid #dedede;
}
.pure-skin-cryto .pure-table caption {
color: #757575;
font: italic 85%/1 arial, sans-serif;
padding: 1em 0;
text-align: center;
}
.pure-skin-cryto .pure-table td,
.pure-skin-cryto .pure-table th {
border-left: 1px solid #dedede;/* inner column border */
border-width: 0 0 0 1px;
font-size: inherit;
margin: 0;
overflow: visible; /*to make ths where the title is really long work*/
padding: 0.3em 0.71em; /* cell padding */
}
.pure-skin-cryto .pure-table td:first-child,
.pure-skin-cryto .pure-table th:first-child {
border-left-width: 0;
}
.pure-skin-cryto .pure-table thead {
background-color: #cfcfcf;
color: #030303;
text-align: left;
vertical-align: bottom;
white-space: nowrap;
}
/*
striping:
even - #fff (white)
odd - #edf5ff (light blue)
*/
.pure-skin-cryto .pure-table td {
background-color: #ededed;
color: #030303;
}
.pure-skin-cryto .pure-table-odd td {
background-color: #dedede;
color: #030303;
}
/* BORDERED TABLES */
.pure-skin-cryto .pure-table-bordered td {
border-bottom:1px solid #dedede;
}
.pure-skin-cryto .pure-table-bordered tbody > tr:last-child td,
.pure-skin-cryto .pure-table-horizontal tbody > tr:last-child td {
border-bottom-width: 0;
}
/* HORIZONTAL BORDERED TABLES */
.pure-skin-cryto .pure-table-horizontal td,
.pure-skin-cryto .pure-table-horizontal th {
border-width: 0 0 1px 0;
border-bottom:1px solid #dedede;
}
.pure-skin-cryto .pure-table-horizontal tbody > tr:last-child td {
border-bottom-width: 0;
}
/* from YUICSS list-core.css */
/*csslint adjoining-classes:false, outline-none:false*/
/*TODO: Remove this lint rule override after a refactor of this code.*/
.pure-skin-cryto .pure-menu ul {
position: absolute;
visibility: hidden;
}
.pure-skin-cryto .pure-menu.pure-menu-open {
visibility: visible;
z-index: 2;
width: 100%;
}
.pure-skin-cryto .pure-menu ul {
left: -10000px;
list-style: none;
margin: 0;
padding: 0;
top: -10000px;
z-index: 1;
}
.pure-skin-cryto .pure-menu > ul { position: relative; }
.pure-skin-cryto .pure-menu-open > ul {
left: 0;
top: 0;
visibility: visible;
}
.pure-skin-cryto .pure-menu-open > ul:focus {
outline: none;
}
.pure-skin-cryto .pure-menu li {
position: relative;
}
.pure-skin-cryto .pure-menu a, .pure-skin-cryto .pure-menu .pure-menu-heading {
display: block;
color: inherit;
line-height: 1.5em;
padding: 0.35em 1.65em;
text-decoration: none;
white-space: nowrap;
}
.pure-skin-cryto .pure-menu.pure-menu-horizontal > .pure-menu-heading {
display: inline-block;
*display: inline;
zoom: 1;
margin: 0;
vertical-align: middle;
}
.pure-skin-cryto .pure-menu.pure-menu-horizontal > ul {
display: inline-block;
*display: inline;
zoom: 1;
vertical-align: middle;
height: 2.4em;
}
.pure-skin-cryto .pure-menu li a { padding: 0.35em 1.65em; }
.pure-skin-cryto .pure-menu-can-have-children > .pure-menu-label:after {
content: '\25B8';
float: right;
font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'DejaVu Sans', sans-serif; /* These specific fonts have the Unicode char we need. */
margin-right: -20px;
margin-top: -1px;
}
.pure-skin-cryto .pure-menu-can-have-children > .pure-menu-label {
padding-right: 30px;
}
.pure-skin-cryto .pure-menu-separator {
background-color: #dedede;
display: block;
height: 1px;
font-size: 0;
margin: 7px 2px;
overflow: hidden;
}
.pure-skin-cryto .pure-menu-hidden {
display: none;
}
/* FIXED MENU */
.pure-skin-cryto .pure-menu-fixed {
position: fixed;
top:0;
left:0;
width: 100%;
}
/* HORIZONTAL MENU CODE */
/* Initial menus should be inline-block so that they are horizontal */
.pure-skin-cryto .pure-menu-horizontal li {
display: inline-block;
*display: inline;
zoom: 1;
vertical-align: middle;
}
/* Submenus should still be display:block; */
.pure-skin-cryto .pure-menu-horizontal li li {
display: block;
}
/* Content after should be down arrow */
.pure-skin-cryto .pure-menu-horizontal > .pure-menu-children > .pure-menu-can-have-children > .pure-menu-label:after {
content: "\25BE";
}
/*Add extra padding to elements that have the arrow so that the hover looks nice */
.pure-skin-cryto .pure-menu-horizontal > .pure-menu-children > .pure-menu-can-have-children > .pure-menu-label {
padding-right:30px;
}
/* Adjusting separator for vertical menus */
.pure-skin-cryto .pure-menu-horizontal li.pure-menu-separator {
height: 50%;
width: 1px;
margin: 0 7px;
}
/* Submenus should be horizontal separator again */
.pure-skin-cryto .pure-menu-horizontal li li.pure-menu-separator {
height: 1px;
width: auto;
margin: 7px 2px;
}
/* end from yuicss/list-core.css *******************************************/
/* from yuicss list-paginator.css */
/*csslint box-model:false*/
/*TODO: Remove this lint rule override after a refactor of this code.*/
.pure-skin-cryto .pure-paginator {
list-style: none;
margin: 0;
padding: 0;
}
.pure-skin-cryto .pure-paginator li {
display: inline-block;
*display: inline;
zoom: 1;
margin: 0 -0.35em 0 0;
}
.pure-skin-cryto .pure-paginator .pure-button {
border-radius: 0;
padding: 0.8em 1.4em;
vertical-align: top;
height: 1.1em;
}
.pure-skin-cryto .pure-paginator .pure-button:focus {
outline-style: none;
}
.pure-skin-cryto .pure-paginator .prev, .pure-skin-cryto .pure-paginator .next {
/*color: #C0C1C3; allow .pure-button to color text*/
}
.pure-skin-cryto .pure-paginator .prev {
border-radius: 4px 0px 0px 4px;
}
.pure-skin-cryto .pure-paginator .next {
border-radius: 0px 4px 4px 0px;
}
/* end from YUICSS list-paginator.css ******************************/
/* from YUICSS list.css *******************************************/
/* MAIN MENU STYLING */
/*csslint adjoining-classes:false*/
/*TODO: Remove this lint rule override after a refactor of this code.*/
.pure-skin-cryto .pure-menu.pure-menu-open,
.pure-skin-cryto .pure-menu.pure-menu-horizontal li .pure-menu-children {
background: #ededed; /* Old browsers */
border: 1px solid #dedede;
}
/* remove borders for horizontal menus */
.pure-skin-cryto .pure-menu.pure-menu-horizontal,
.pure-skin-cryto .pure-menu.pure-menu-horizontal .pure-menu-heading {
border: none;
}
/* LINK STYLES */
.pure-skin-cryto .pure-menu a {
border: 1px solid transparent;
border-left: none;
border-right: none;
}
.pure-skin-cryto .pure-menu a,
.pure-skin-cryto .pure-menu .pure-menu-can-have-children > li:after {
color: #030303;
}
.pure-skin-cryto .pure-menu .pure-menu-can-have-children > li:hover:after {
color: #030303;
}
/* Focus style for a dropdown menu-item when the parent has been opened */
.pure-skin-cryto .pure-menu .pure-menu-open {
background: #d6d6d6;
}
/* HOVER STATES */
.pure-skin-cryto .pure-menu li a:hover {
background: #d6d6d6;
}
/* DISABLED STATES */
.pure-skin-cryto .pure-menu li.pure-menu-disabled a:hover {
background: #ededed;
color: #666666;
}
.pure-skin-cryto .pure-menu .pure-menu-disabled > a {
background-image: none;
border-color: transparent;
cursor: default;
}
.pure-skin-cryto .pure-menu .pure-menu-disabled > a,
.pure-skin-cryto .pure-menu .pure-menu-can-have-children.pure-menu-disabled > a:after {
color: #666666;
}
/* HEADINGS */
.pure-skin-cryto .pure-menu .pure-menu-heading {
color: #030303;
text-transform: uppercase;
font-size: 90%;
margin-top: 0.5em;
border-bottom: solid 1px #dedede;
}
/* SELECTED MENU ITEM */
.pure-skin-cryto .pure-menu li.pure-menu-selected a {
background-color: #303030;
color: #fcfcfc;
}
/* FIXED MENU */
.pure-skin-cryto .pure-menu.pure-menu-open.pure-menu-fixed {
border: none;
border-bottom: 1px solid #dedede;
}
/* end from YUICSS list.css ***********************************/
/* from YUICSS list-responsive.css ****************************/
/* RESPONSIVE */
@media (max-width: 480px) {
.pure-skin-cryto .pure-menu-horizontal {
width:100%;
}
.pure-skin-cryto .pure-menu-children li {
display: block;
border-bottom:1px solid #dedede;
}
}
/* end from list-responsive.css ******************/

@ -0,0 +1,226 @@
html, body
{
font-family: Arial, Verdana;
background-color: #EDEDED;
}
body
{
margin: 8px;
}
div.wrapper
{
width: 900px;
margin: 0px auto;
background-image: url(http://tahoe-gateway.cryto.net:3719/download/VVJJOkNISzp1a3R4YmRkZ3M3djZubGV2Y2N5dW1obHA2NDpjMzdzZ2lpN2h6NHFiNWlneGZnb2YyNWp3NXlrZXp5azZoaGt2MjV1eTYydDVkNjdvd21xOjM6NjoyNjk3MA==/cubes.png);
background-repeat: no-repeat;
background-position: right top;
}
div.header
{
margin: 0px 5px;
margin-bottom: 8px;
border-bottom: 3px solid #2B2B2B;
margin-right: 175px;
}
div.header h1, h2
{
display: inline;
color: #2B2B2B;
}
div.header h2
{
margin-left: 25px;
color: #696969;
}
div.menu
{
margin: 0px 5px;
background-color: black;
padding: 3px;
padding-top: 5px;
margin-right: 175px;
}
div.menu a
{
font-size: 13px;
font-weight: bold;
color: white;
text-decoration: none;
padding: 4px;
}
div.menu a:hover
{
color: black;
background-color: #EDEDED;
}
div.content
{
margin: 0px 9px;
margin-right: 202px;
text-align: justify;
}
div.content h3
{
margin-bottom: 2px;
}
div.content p
{
margin-top: 7px;
margin-bottom: 10px;
}
div.content table, div.content th, div.content td
{
border: 1px solid black;
border-collapse: collapse;
}
div.content table
{
margin: 0px auto;
}
div.content th, div.content td
{
padding: 2px 5px;
}
div.content th
{
text-align: left;
}
div.content table.no-border, div.content table.no-border th, div.content table.no-border td
{
border: 0px solid transparent;
margin: 0px;
padding-right: 13px;
padding-left: 0px;
}
div.content h2
{
margin-top: 20px;
margin-bottom: 5px;
}
div.footer
{
border-top: 2px solid #2B2B2B;
padding-top: 3px;
margin: 0px 5px;
margin-top: 13px;
font-size: 11px;
background-color: #EDEDED;
}
pre.bash, div.notice
{
border: 1px dashed black;
margin: 0px;
padding: 2px 5px;
background-color: #F1F1F1;
}
div.notice
{
margin-top: 9px;
}
div.notice-one, div.notice-three
{
font-size: 19px;
font-weight: bold;
}
div.notice-two
{
font-size: 31px;
font-weight: bold;
text-align: center;
}
div.notice-three
{
margin-top: 2px;
text-align: right;
}
div.error
{
border: 1px solid #5D0000;
background-color: #E2C6C6;
margin-top: 8px;
margin-bottom: 6px;
font-size: 15px;
padding: 8px 10px;
}
div.error ul
{
padding-left: 28px;
margin: 3px 0px;
}
div.error p
{
margin: 3px 0px;
font-weight: bold;
font-size: 16px;
}
.login
{
float: right;
margin-top: -2px;
}
.login input, .login button
{
font-size: 13px;
}
.login input
{
width: 105px;
padding: 2px 3px;
border: 1px solid gray;
border-radius: 2px;
}
.login button
{
border: 1px solid gray;
padding: 2px 6px;
border-radius: 2px;
}
.pure-skin-cryto .pure-form input[type="text"],
.pure-skin-cryto .pure-form input[type="password"],
.pure-skin-cryto .pure-form input[type="email"],
.pure-skin-cryto .pure-form input[type="url"],
.pure-skin-cryto .pure-form input[type="date"],
.pure-skin-cryto .pure-form input[type="month"],
.pure-skin-cryto .pure-form input[type="time"],
.pure-skin-cryto .pure-form input[type="datetime"],
.pure-skin-cryto .pure-form input[type="datetime-local"],
.pure-skin-cryto .pure-form input[type="week"],
.pure-skin-cryto .pure-form input[type="number"],
.pure-skin-cryto .pure-form input[type="search"],
.pure-skin-cryto .pure-form input[type="tel"],
.pure-skin-cryto .pure-form input[type="color"],
.pure-skin-cryto .pure-form select,
.pure-skin-cryto .pure-form textarea {
border: 1px solid #DADADA;
}

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<title>Cryto Coding Collective :: {%?title}</title>
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.2.0/pure-min.css">
<link rel="stylesheet" type="text/css" href="/static/pure.css">
<link rel="stylesheet" type="text/css" href="/static/style.css">
</head>
<body class="pure-skin-cryto">
<div class="wrapper">
<div class="header">
<h1>Cryto Coding Collective</h1>
<h2>{%?header}</h2>
</div>
<div class="menu">
<div class="login">
{%if logged-in == false}
<form method="post" action="/login">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<button type="submit">Login</button>
</form>
{%else}
You are already logged in.
{%/if}
</div>
<a href="/">Home</a>
<a href="/projects/">Projects</a>
<a href="/guides/">Guides</a>
<a href="/mirrors/">Mirrors</a>
<a href="/irc/">IRC</a>
<a href="/donate/">Donate</a>
</div>
<div class="content">
{%if isempty|errors == false}
<div class="error">
<p>One or more errors occurred:</p>
<ul>
{%foreach error in errors}
<li>{%?error}</li>
{%/foreach}
</ul>
</div>
{%/if}
{%?contents}
</div>
<div class="footer">
The design and contents of this website are, unless specified otherwise, licensed under
WTFPL - which essentially means you can do with it whatever you want. Individual downloads
may be licensed under a different license. Be sure to check the LICENSE file when
downloading an archive.
</div>
</div>
</body>
</html>

@ -0,0 +1,28 @@
<h3>Register</h3>
<form method="post" action="/register" class="pure-form pure-form-aligned">
<div class="pure-control-group">
<label>Username</label>
{%input type="text" name="username"}
</div>
<div class="pure-control-group">
<label>E-mail address</label>
{%input type="text" name="email"}
</div>
<div class="pure-control-group">
<label>Password</label>
{%input type="password" name="password"}
</div>
<div class="pure-control-group">
<label>Password (again)</label>
{%input type="password" name="password2"}
</div>
<div class="pure-control-group">
<label></label>
<button type="submit" class="pure-button pure-button-primary">Register</button>
</div>
</form>
Loading…
Cancel
Save