Skip to content

Instantly share code, notes, and snippets.

@Bouhnosaure
Created February 1, 2016 20:25
Show Gist options
  • Save Bouhnosaure/a4c73772846d1be14bb7 to your computer and use it in GitHub Desktop.
Save Bouhnosaure/a4c73772846d1be14bb7 to your computer and use it in GitHub Desktop.
<?php
/*!
* OS.js - JavaScript Operating System
*
* Mysql Handler: Login screen and session/settings handling via database
* PLEASE NOTE THAT THIS AN EXAMPLE ONLY, AND SHOUD BE MODIFIED BEFORE USAGE
*
* Copyright (c) 2011-2016, Anders Evenrud <andersevenrud@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @author Anders Evenrud <andersevenrud@gmail.com>
* @licence Simplified BSD License
*/
/*
See doc/example-handler.txt
*/
define("APIHANDLER_DSN", "mysql:host=localhost;dbname=osjs");
define("APIHANDLER_USER", "osjs");
define("APIHANDLER_PASS", "osjs");
define("PASSWORD_BCRYPT", true);
/**
* MysqlAPIHandler for sessions via database
*/
class MysqlAPIHandler
{
/**
* Create the database connection
* @return PDO
* @throws Exception
*/
protected static function _initDB() {
$args = [1002 => "SET NAMES 'utf8'"];
if ( !($db = new PDO(APIHANDLER_DSN, APIHANDLER_USER, APIHANDLER_PASS, $args)) ) {
throw new Exception("Could not set up database connection");
}
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $db;
}
/**
* This login an user
*
* @param array $arguments
* @return array
* @throws Exception
*/
public static function login(array $arguments) {
$db = self::_initDB();
unset($_SESSION['user']);
self::checkPassword($arguments['username'], $arguments['password']);
$q = "SELECT `id`, `username`, `name`, `groups`, `settings` FROM `users` WHERE `username` = ? LIMIT 1;";
$a = [$arguments['username']];
$response = false;
if ( $stmt = $db->prepare($q) ) {
$stmt->setFetchMode(PDO::FETCH_ASSOC);
if ( $stmt->execute($a) ) {
if ( $row = $stmt->fetch() ) {
$response = [
"userData" => [
"id" => (int)$row['id'],
"username" => $row['username'],
"name" => $row['name'],
"groups" => (array)json_decode($row['groups'])
],
"userSettings" => (array)json_decode($row['settings'])
];
if ( !$response['userData']['groups'] ) {
$response['userData']['groups'] = [];
}
if ( !$response['userSettings'] ) {
$response['userSettings'] = null;
}
}
}
}
if ( $response ) {
$settings = Settings::get();
$user = APIUser::login($response["userData"]);
$homedir = sprintf("%s/%s", $settings['vfs']['homes'], $user->getUsername());
if ( !file_exists($homedir) ) {
@mkdir($homedir);
@mkdir("{$homedir}/.packages");
}
}
return [false, $response];
}
/**
* This logout the authenticated user
*
* @param array $arguments
* @return array
* @throws Exception
*/
public static function logout(array $arguments) {
$db = self::_initDB();
APIUser::logout();
return [false, true];
}
/**
* This updates the settings of the authenticated user
*
* @param array $arguments
* @return array
* @throws Exception
*/
public static function settings(array $arguments) {
$db = self::_initDB();
$result = false;
if ( !isset($_SESSION['user']) ) {
throw new Exception("Cannot set settings without user session");
}
$q = "UPDATE `users` SET `settings` = ? WHERE `id` = ?;";
$a = [json_encode($arguments['settings']), $_SESSION['user']['id']];
if ( $stmt = $db->prepare($q) ) {
$result = $stmt->execute($a);
}
return [false, $result];
}
/**
* This checks the password for a given username
*
* @param $username
* @param $password
* @return bool
* @throws Exception
*/
public static function checkPassword($username, $password) {
$db = self::_initDB();
$q = "SELECT `password` FROM `osjs_users` WHERE `username` = ? LIMIT 1;";
$a = [$username];
if ( $stmt = $db->prepare($q) ) {
$stmt->setFetchMode(PDO::FETCH_ASSOC);
if ( $stmt->execute($a) ) {
if ( $row = $stmt->fetch() ) {
if ( PASSWORD_BCRYPT === true) {
$status = password_verify($password, $row['password']);
} else {
$status = ($password == $row['password']);
}
if ( $status ) {
return true;
}
}
}
}
throw new Exception("Invalid login credentials");
}
/**
* This enables full privileges for all users. Simply remove to make use of the groups
*
* @see APIUser
* @param null $requires
* @throws Exception
*/
public static function checkPrivilege($requires = null) {
APIHandler::checkPrivilege(true);
}
}
API::AddHandler('login', ['MysqlAPIHandler', 'login']);
API::AddHandler('logout', ['MysqlAPIHandler', 'logout']);
API::AddHandler('settings', ['MysqlAPIHandler', 'settings']);
API::SetHandler('MysqlAPIHandler');
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment