Page MenuHomeDevCentral

No OneTemporary

diff --git a/includes/objects/user.php b/includes/objects/user.php
index 707de43..ad1137e 100755
--- a/includes/objects/user.php
+++ b/includes/objects/user.php
@@ -1,404 +1,412 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* User class
*
* @package ObsidianWorkspaces
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*
*/
/**
* User class
*/
class User {
public $id;
public $name;
public $password;
public $active = 0;
public $email;
public $regdate;
/**
* @var Array An array of users already loaded, the username as user id
*/
public static $hashtableById = [];
+ /**
+ * @var array|null An array of the workspaces the user has access to, each element an instance of the Workspace object. As long as the field hasn't been initialized by get_workspaces, null.
+ */
+ private $workspaces = null;
+
/*
* Initializes a new instance
*
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Initializes a new User instance if needed or get already available one.
*
* @param iint $id the user ID
* @return User the user instance
*/
static function get ($id = NULL) {
if ($id && array_key_exists($id, User::$hashtableById)) {
return self::$hashtableById[$id];
}
$user = new self($id);
return $user;
}
/**
* Loads the object User (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('password', $_POST)) $this->password = $_POST['password'];
if (array_key_exists('active', $_POST)) $this->active = $_POST['active'];
if (array_key_exists('actkey', $_POST)) $this->actkey = $_POST['actkey'];
if (array_key_exists('email', $_POST)) $this->email = $_POST['email'];
if (array_key_exists('regdate', $_POST)) $this->regdate = $_POST['regdate'];
}
/**
* Loads the object User (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$sql = "SELECT * FROM " . TABLE_USERS . " WHERE user_id = '" . $this->id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query users", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "User unkwown: " . $this->id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Loads the object User (ie fill the properties) from the database row
*/
function load_from_row ($row) {
$this->id = $row['user_id'];
$this->name = $row['username'];
$this->password = $row['user_password'];
$this->active = $row['user_active'] ? true : false;
$this->email = $row['user_email'];
$this->regdate = $row['user_regdate'];
//Puts object in hashtable, so it's accessible in future call of
//this run through User::get($id).
self::$hashtableById[$this->id] = $this;
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$name = $db->sql_escape($this->name);
$password = $db->sql_escape($this->password);
$active = $this->active ? 1 : 0;
$email = $db->sql_escape($this->email);
$regdate = $this->regdate ? "'" . $db->sql_escape($this->regdate) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_USERS . " (`user_id`, `username`, `user_password`, `user_active`, `user_email`, `user_regdate`) VALUES ($id, '$name', '$password', $active, '$email', $regdate)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save user", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/**
* Updates the specified field in the database record
*/
function save_field ($field) {
global $db;
if (!$this->id) {
message_die(GENERAL_ERROR, "You're trying to update a record not yet saved in the database");
}
$id = $db->sql_escape($this->id);
$value = $db->sql_escape($this->$field);
$sql = "UPDATE " . TABLE_USERS . " SET `$field` = '$value' WHERE user_id = '$id'";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save $field field", '', __LINE__, __FILE__, $sql);
}
}
//
// USER MANAGEMENT FUNCTIONS
//
/**
* Generates a unique user id
*/
function generate_id () {
global $db;
do {
$this->id = mt_rand(2001, 9999);
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE user_id = $this->id";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't check if a user id is free", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
} while ($row[0]);
}
/**
* Fills password field with encrypted version
* of the specified clear password
*/
public function set_password ($newpassword) {
$this->password = md5($newpassword);
}
/**
* Checks if a login is available
*
* @param string $login the login to check
* @return boolean true if the login is avaiable; otherwise, false.
*/
public static function is_available_login ($login) {
global $db;
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE username = '$login'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't check if the specified login is available", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] == 0);
}
/**
* Initializes a new User instance ready to have its property filled
*
* @return User the new user instance
*/
public static function create () {
$user = new User();
$user->generate_id();
$user->active = true;
$user->regdate = time();
return $user;
}
/**
* Gets user from specified e-mail
*
* @return User the user matching the specified e-mail; null, if the mail were not found.
*/
public static function get_user_from_email ($mail) {
global $db;
$sql = "SELECT * FROM " . TABLE_USERS . " WHERE user_email = '$mail'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get user", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
//E-mail found.
$user = new User();
$user->load_from_row($row);
return $user;
}
//E-mail not found.
return null;
}
//
// REMOTE IDENTITY PROVIDERS
//
/**
* Gets user from remote identity provider identifiant
*
* @param $authType The authentication method type
* @param $remoteUserId The remote user idenfifiant
* @return User the user matching the specified identity provider and identifiant; null if no user were found.
*/
public static function getUserFromRemoteIdentity ($authType, $remoteUserId) {
global $db;
$authType = $db->sql_escape($authType);
$remoteUserId = $db->sql_escape($remoteUserId);
$sql = "SELECT user_id FROM " . TABLE_USERS_AUTH . " WHERE "
. "auth_type = '$authType' AND auth_identity = '$remoteUserId'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get user", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return User::get($row['user_id']);
}
return null;
}
/**
* Sets user's remote identity provider identifiant
*
* @param $authType The authentication method type
* @param $remoteUserId The remote user idenfifiant
* */
public function setRemoteIdentity ($authType, $remoteUserId, $properties = null) {
global $db;
$authType = $db->sql_escape($authType);
$remoteUserId = $db->sql_escape($remoteUserId);
$properties = ($properties === NULL) ? 'NULL' : "'" . $db->sql_escape($properties) . "'";
$sql = "INSERT INTO " . TABLE_USERS_AUTH . " (auth_type, auth_identity, auth_properties, user_id) "
. "VALUES ('$authType', '$remoteUserId', $properties, $this->id)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't set user remote identity provider information", '', __LINE__, __FILE__, $sql);
}
}
//
// INTERACTION WITH OTHER OBJECTS
//
/**
* Gets the groups where the current user has access to.
*
* @return array an array containing group_id, matching groups the current user has access to.
*/
public function get_groups () {
return self::get_groups_from_user_id($this->id);
}
/**
* Determines if the user is a member of the specified group
*
* @param UserGroup $group The group to check
*/
public function isMemberOfGroup (UserGroup $group) {
global $db;
$sql = "SELECT count(*) FROM users_groups_members WHERE group_id = $group->id AND user_id = $this->id";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't determine if the user belongs to the group", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return $row[0] == 1;
}
/**
* Adds user to the specified group
*
* @param UserGroup $group The group where to add the user
* @parap boolean $isAdmin if true, set the user admin; otherwise, set it regular user.
*/
public function addToGroup (UserGroup $group, $isAdmin = false) {
global $db;
$isAdmin = $isAdmin ? 1 : 0;
$sql = "REPLACE INTO users_groups_members VALUES ($group->id, $this->id, $isAdmin)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't add user to group", '', __LINE__, __FILE__, $sql);
}
}
/**
* Gets the SQL permission clause to select resources where the user is the subject.
*
* @return string The SQL WHERE clause
*/
public function get_permissions_clause () {
return self::get_permissions_clause_from_user_id($this->id);
}
/**
* Gets workspaces this user has accces to.
*
* @return Array A list of workspaces
*/
public function get_workspaces () {
- return Workspace::get_user_workspaces($this->id);
+ if ($this->workspaces === null) {
+ $this->workspaces = Workspace::get_user_workspaces($this->id);
+ }
+ return $this->workspaces;
}
/**
* Sets user permission
*
* @param string $resourceType The target resource type
* @param int $resourceId The target resource ID
* @param string $permissionName The permission name
* @param int $permissionFlag The permission flag (facultative; by default, 1)
*/
public function setPermission ($resourceType, $resourceId, $permissionName, $permissionFlag = 1) {
global $db;
$resourceType = $db->sql_escape($resourceType);
if (!is_numeric($resourceId)) {
throw new Exception("Resource ID must be a positive or null integer, and not $resourceId.");
}
$permissionName = $db->sql_escape($permissionName);
if (!is_numeric($permissionFlag)) {
throw new Exception("Permission flag must be a positive or null integer, and not $permissionFlag.");
}
$sql = "REPLACE INTO permissions
(subject_resource_type, subject_resource_id,
target_resource_type, target_resource_id,
permission_name, permission_flag)
VALUES
('U', $this->id,
'$resourceType', $resourceId,
'$permissionName', $permissionFlag)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't set user permission", '', __LINE__, __FILE__, $sql);
}
}
/**
* Gets the groups where an user has access to.
*
* @param int $user_id the user to get the groups list
* @return array an array containing group_id, matching groups the specified user has access to.
*/
public static function get_groups_from_user_id ($user_id) {
global $db;
$sql = "SELECT group_id FROM " . TABLE_UGROUPS_MEMBERS . " WHERE user_id = " . $user_id;
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get user groups", '', __LINE__, __FILE__, $sql);
}
$gids = array();
while ($row = $db->sql_fetchrow($result)) {
$gids[] = $row['group_id'];
}
return $gids;
}
/**
* Gets the SQL permission clause to select resources where the specified user is the subject.
*
* @param $user_id The user ID
* @return string The SQL WHERE clause
*/
public static function get_permissions_clause_from_user_id ($user_id) {
$clause = "subject_resource_type = 'U' AND subject_resource_id = $user_id";
if ($groups = self::get_groups_from_user_id ($user_id)) {
$clause = "($clause) OR (subject_resource_type = 'G' AND subject_resource_id = ";
$clause .= join(") OR (subject_resource_type = 'G' AND subject_resource_id = ", $groups);
$clause .= ')';
}
return $clause;
}
}
diff --git a/includes/workspaces/Workspace.php b/includes/workspaces/Workspace.php
index bdf00bc..b772d18 100644
--- a/includes/workspaces/Workspace.php
+++ b/includes/workspaces/Workspace.php
@@ -1,202 +1,221 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Workspace class
*
* @package ObsidianWorkspaces
* @subpackage Workspaces
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*/
/**
* Workspace class
*
* This class maps the workspaces table.
*/
class Workspace {
public $id;
public $code;
public $name;
public $created;
public $description;
/**
* @var WorkspaceConfiguration The workspace configuration
*/
public $configuration;
/**
* Initializes a new instance
*
* @param int $id the primary key
*/
function __construct ($id = NULL) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Loads the object Workspace (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('code', $_POST)) $this->code = $_POST['code'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('created', $_POST)) $this->created = $_POST['created'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
}
/**
* Loads the object zone (ie fill the properties) from the $row array
*/
function load_from_row ($row) {
$this->id = $row['workspace_id'];
$this->code = $row['workspace_code'];
$this->name = $row['workspace_name'];
$this->created = $row['workspace_created'];
$this->description = $row['workspace_description'];
}
/**
* Loads the specified workspace from code
*
* @param string $code The workspace code
* @return Workspace The specified workspace instance
*/
public static function fromCode ($code) {
global $db;
$code = $db->sql_escape($code);
$sql = "SELECT * FROM " . TABLE_WORKSPACES . " WHERE workspace_code = '" . $code . "'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Unable to query workspaces", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
throw new Exception("Workspace unkwown: " . $code);
}
$workspace = new Workspace();
$workspace->load_from_row($row);
return $workspace;
}
/**
* Loads the object Workspace (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_WORKSPACES . " WHERE workspace_id = '" . $id . "'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Unable to query workspaces", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Workspace unkwown: " . $this->id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$code = $db->sql_escape($this->code);
$name = $db->sql_escape($this->name);
$created = $db->sql_escape($this->created);
$description = $db->sql_escape($this->description);
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_WORKSPACES . " (`workspace_id`, `workspace_code`, `workspace_name`, `workspace_created`, `workspace_description`) VALUES ('$id', '$code', '$name', '$created', '$description')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
+ /**
+ * Determines if the specified user has access to the current workspace
+ *
+ * @param User the user to check
+ * @return boolean true if the user has access to the current workspace ; otherwise, false.
+ */
+ public function userCanAccess (User $user) {
+ if ($this->id === false || $this->id === null || $this->id === '') {
+ throw new LogicException("The workspace must has a valid id before to call userCanAccess.");
+ }
+ foreach ($user->get_workspaces() as $workspace) {
+ if ($workspace->id == $this->id) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Loads configuration
*
* @param $context The site context
*/
public function loadConfiguration (Context $context) {
global $Config;
$file = $Config['Content']['Workspaces'] . '/' . $this->code . '/workspace.conf';
if (!file_exists($file)) {
throw new Exception("Workspace configuration file doesn't exist");
}
$this->configuration = WorkspaceConfiguration::loadFromFile($file, $context);
}
/**
* Gets workspaces specified user has access to.
*
* @param int $user_id The user to get his workspaces
* @return Array A list of workspaces
*/
public static function get_user_workspaces ($user_id) {
global $db;
//Gets the workspaces list from cache, as this complex request could take 100ms
//and is called on every page.
$cache = Cache::load();
if (!$workspaces = unserialize($cache->get("workspaces-$user_id"))) {
$clause = User::get_permissions_clause_from_user_id($user_id);
$sql = "SELECT DISTINCT w.*
FROM " . TABLE_PERMISSIONS . " p, " . TABLE_WORKSPACES . " w
WHERE p.target_resource_type = 'W' AND
p.target_resource_id = w.workspace_id AND
p.permission_name = 'accessLevel' AND
+ p.permission_flag > 0 AND
($clause)";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get user workspaces", '', __LINE__, __FILE__, $sql);
}
$workspaces = array();
while ($row = $db->sql_fetchrow($result)) {
$workspace = new Workspace();
$workspace->id = $row['workspace_id'];
$workspace->load_from_row($row);
$workspaces[] = $workspace;
}
$cache->set("workspaces-$user_id", serialize($workspaces));
}
return $workspaces;
}
/**
* Determines if a string matches an existing workspace code.
*
* @param string $code The workspace code to check
* @return boolean If the specified code matches an existing workspace, true; otherwise, false.
*/
public static function is_workspace ($code) {
global $db;
$code = $db->sql_escape($code);
$sql = "SELECT count(*) FROM " . TABLE_WORKSPACES . " WHERE workspace_code = '$code'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't check workspace code", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] == 1);
}
}
diff --git a/index.php b/index.php
index 8b84afe..7ad5f08 100755
--- a/index.php
+++ b/index.php
@@ -1,91 +1,96 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Main web application entry point
*
* @package ObsidianWorkspaces
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*
*/
////////////////////////////////////////////////////////////////////////////////
///
/// Initialization
///
//Keruald and Obsidian Workspaces libraries
include('includes/core.php');
//Prepares the site context
$context = new Context();
$context->config = $Config;
$context->db = $db = Database::load($context);
$context->session = Session::load();
$context->url = get_current_url_fragments();
$context->initializeTemplateEngine($context->config['Theme']);
//Loads language files
Language::initialize();
Language::load($context)->configLoad('core.conf');
//Loads workspace
if (Workspace::is_workspace($context->url[0])) {
$context->workspace = Workspace::fromCode(array_shift($context->url));
$context->workspace->loadConfiguration($context);
}
//Handles login or logout
include("includes/login.php");
//Gets current user information
$context->user = $context->session->get_logged_user();
////////////////////////////////////////////////////////////////////////////////
///
/// Serves the requested page
///
//If the user isn't logged in (is anonymous), prints login/invite page & dies.
if ($context->user->id == ANONYMOUS_USER) {
//Anonymous user
include('controllers/anonymous.php');
exit;
}
+//If a workspace has been selected, ensures the current logged in user has access to it.
+if ($context->workspace && !$context->workspace->userCanAccess($context->user)) {
+ message_die(HACK_ERROR, "You don't have access to this workspace.", 'Access control');
+}
+
$controller = count($context->url) > 0 ? $context->url[0] : '';
switch ($controller) {
case '':
//Calls homepage controller
HomepageController::run($context);
break;
case 'help':
case 'reports':
//Calls requested controller
include("controllers/$controller.php");
break;
default:
//Current workspace application controller?
$workspaceConfig = $context->workspace->configuration;
$applicationConfiguration = NULL;
if ($workspaceConfig != NULL && $workspaceConfig->hasControllerBind($controller, $applicationConfiguration)) {
//Runs controller
$controllerClass = $applicationConfiguration->name;
$appContext = ApplicationContext::loadFromContext($context, $applicationConfiguration);
$controllerClass::run($appContext);
break;
}
//Not a workspace, nor a controller toponomy
ErrorPageController::show($context, 404);
exit;
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Oct 22, 12:43 (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3092157
Default Alt Text
(25 KB)

Event Timeline