Multiply changes to user system

keeping tracked of the logged in user is no longer done by the active backend but by oc_user directly instead

multiply backends can be active at the same time, allowing alternative authentication procedures like openid or tokens to be used next to the regular user system
This commit is contained in:
Robin Appelman 2011-06-21 19:28:46 +02:00
parent c36b8621b4
commit ee0f1490e1
4 changed files with 127 additions and 139 deletions

View file

@ -21,7 +21,10 @@
*
*/
/**
* error code for functions not provided by the storage provider
*/
define('OC_USER_BACKEND_NOT_IMPLEMENTED',-501);
/**
* abstract base class for user management
@ -37,7 +40,9 @@ abstract class OC_USER_BACKEND {
* Creates a new user. Basic checking of username is done in OC_USER
* itself, not in its subclasses.
*/
public static function createUser($uid, $password){}
public function createUser($uid, $password){
return OC_USER_BACKEND_NOT_IMPLEMENTED;
}
/**
* @brief delete a user
@ -46,41 +51,9 @@ abstract class OC_USER_BACKEND {
*
* Deletes a user
*/
public static function deleteUser( $uid ){}
/**
* @brief Try to login a user
* @param $uid The username of the user to log in
* @param $password The password of the user
* @returns true/false
*
* Log in a user - if the password is ok
*/
public static function login($uid, $password){}
/**
* @brief Kick the user
* @returns true
*
* Logout, destroys session
*/
public static function logout(){}
/**
* @brief Check if the user is logged in
* @returns true/false
*
* Checks if the user is logged in
*/
public static function isLoggedIn(){}
/**
* @brief Autogenerate a password
* @returns string
*
* generates a password
*/
public static function generatePassword(){}
public function deleteUser( $uid ){
return OC_USER_BACKEND_NOT_IMPLEMENTED;
}
/**
* @brief Set password
@ -90,7 +63,9 @@ abstract class OC_USER_BACKEND {
*
* Change the password of a user
*/
public static function setPassword($uid, $password){}
public function setPassword($uid, $password){
return OC_USER_BACKEND_NOT_IMPLEMENTED;
}
/**
* @brief Check if the password is correct
@ -100,7 +75,9 @@ abstract class OC_USER_BACKEND {
*
* Check if the password is correct without logging in the user
*/
public static function checkPassword($uid, $password){}
public function checkPassword($uid, $password){
return OC_USER_BACKEND_NOT_IMPLEMENTED;
}
/**
* @brief Get a list of all users
@ -108,5 +85,16 @@ abstract class OC_USER_BACKEND {
*
* Get a list of all users.
*/
public static function getUsers(){}
public function getUsers(){
return OC_USER_BACKEND_NOT_IMPLEMENTED;
}
/**
* @brief check if a user exists
* @param string $uid the username
* @return boolean
*/
public function userExists($uid){
return OC_USER_BACKEND_NOT_IMPLEMENTED;
}
}

View file

@ -50,12 +50,8 @@ class OC_USER_DATABASE extends OC_USER_BACKEND {
* Creates a new user. Basic checking of username is done in OC_USER
* itself, not in its subclasses.
*/
public static function createUser( $uid, $password ){
// Check if the user already exists
$query = OC_DB::prepare( "SELECT * FROM `*PREFIX*users` WHERE uid = ?" );
$result = $query->execute( array( $uid ));
if ( $result->numRows() > 0 ){
public function createUser( $uid, $password ){
if( $this->userExists($uid) ){
return false;
}
else{
@ -73,76 +69,13 @@ class OC_USER_DATABASE extends OC_USER_BACKEND {
*
* Deletes a user
*/
public static function deleteUser( $uid ){
public function deleteUser( $uid ){
// Delete user-group-relation
$query = OC_DB::prepare( "DELETE FROM `*PREFIX*users` WHERE uid = ?" );
$result = $query->execute( array( $uid ));
return true;
}
/**
* @brief Try to login a user
* @param $uid The username of the user to log in
* @param $password The password of the user
* @returns true/false
*
* Log in a user - if the password is ok
*/
public static function login( $uid, $password ){
// Query
$query = OC_DB::prepare( "SELECT uid FROM *PREFIX*users WHERE uid = ? AND password = ?" );
$result = $query->execute( array( $uid, sha1( $password )));
if( $result->numRows() > 0 ){
// Set username if name and password are known
$row = $result->fetchRow();
$_SESSION['user_id'] = $row["uid"];
OC_LOG::add( "core", $_SESSION['user_id'], "login" );
return true;
}
else{
return false;
}
}
/**
* @brief Kick the user
* @returns true
*
* Logout, destroys session
*/
public static function logout(){
OC_LOG::add( "core", $_SESSION['user_id'], "logout" );
$_SESSION['user_id'] = false;
return true;
}
/**
* @brief Check if the user is logged in
* @returns true/false
*
* Checks if the user is logged in
*/
public static function isLoggedIn() {
if( isset($_SESSION['user_id']) AND $_SESSION['user_id'] ){
return true;
}
else{
return false;
}
}
/**
* @brief Autogenerate a password
* @returns string
*
* generates a password
*/
public static function generatePassword(){
return uniqId();
}
/**
* @brief Set password
* @param $uid The username
@ -151,12 +84,8 @@ class OC_USER_DATABASE extends OC_USER_BACKEND {
*
* Change the password of a user
*/
public static function setPassword( $uid, $password ){
// Check if the user already exists
$query = OC_DB::prepare( "SELECT * FROM `*PREFIX*users` WHERE uid = ?" );
$result = $query->execute( array( $uid ));
if( $result->numRows() > 0 ){
public function setPassword( $uid, $password ){
if( $this->userExists($uid) ){
$query = OC_DB::prepare( "UPDATE *PREFIX*users SET password = ? WHERE uid = ?" );
$result = $query->execute( array( sha1( $password ), $uid ));
@ -175,7 +104,7 @@ class OC_USER_DATABASE extends OC_USER_BACKEND {
*
* Check if the password is correct without logging in the user
*/
public static function checkPassword( $uid, $password ){
public function checkPassword( $uid, $password ){
$query = OC_DB::prepare( "SELECT uid FROM *PREFIX*users WHERE uid = ? AND password = ?" );
$result = $query->execute( array( $uid, sha1( $password )));
@ -193,7 +122,7 @@ class OC_USER_DATABASE extends OC_USER_BACKEND {
*
* Get a list of all users.
*/
public static function getUsers(){
public function getUsers(){
$query = OC_DB::prepare( "SELECT uid FROM *PREFIX*users" );
$result = $query->execute();
@ -203,4 +132,16 @@ class OC_USER_DATABASE extends OC_USER_BACKEND {
}
return $users;
}
/**
* @brief check if a user exists
* @param string $uid the username
* @return boolean
*/
public function userExists($uid){
$query = OC_DB::prepare( "SELECT * FROM `*PREFIX*users` WHERE uid = ?" );
$result = $query->execute( array( $uid ));
return $result->numRows() > 0;
}
}

View file

@ -93,7 +93,7 @@ require_once('search.php');
$error=(count(OC_UTIL::checkServer())>0);
OC_USER::setBackend( OC_CONFIG::getValue( "userbackend", "database" ));
OC_USER::useBackend( OC_CONFIG::getValue( "userbackend", "database" ));
OC_GROUP::setBackend( OC_CONFIG::getValue( "groupbackend", "database" ));
// Set up file system unless forbidden

View file

@ -40,7 +40,7 @@ if( !OC_CONFIG::getValue( "installed", false )){
*/
class OC_USER {
// The backend used for user management
private static $_backend = null;
private static $_usedBackends = array();
// Backends available (except database)
private static $_backends = array();
@ -66,15 +66,25 @@ class OC_USER {
public static function getBackends(){
return self::$_backends;
}
/**
* @brief gets used backends
* @returns array of backends
*
* Returns the names of all used backends.
*/
public static function getUsedBackends(){
return array_keys(self::$_usedBackends);
}
/**
* @brief Sets the backend
* @brief Adds the backend to the list of used backends
* @param $backend default: database The backend to use for user managment
* @returns true/false
*
* Set the User Authentication Module
*/
public static function setBackend( $backend = 'database' ){
public static function useBackend( $backend = 'database' ){
// You'll never know what happens
if( null === $backend OR !is_string( $backend )){
$backend = 'database';
@ -86,11 +96,11 @@ class OC_USER {
case 'mysql':
case 'sqlite':
require_once('User/database.php');
self::$_backend = new OC_USER_DATABASE();
self::$_usedBackends[$backend] = new OC_USER_DATABASE();
break;
default:
$className = 'OC_USER_' . strToUpper($backend);
self::$_backend = new $className();
self::$_usedBackends[$backend] = new $className();
break;
}
@ -119,7 +129,7 @@ class OC_USER {
return false;
}
// Check if user already exists
if( in_array( $uid, self::getUsers())){
if( self::userExists($uid) ){
return false;
}
@ -127,13 +137,17 @@ class OC_USER {
$run = true;
OC_HOOK::emit( "OC_USER", "pre_createUser", array( "run" => &$run, "uid" => $uid, "password" => $password ));
if( $run && self::$_backend->createUser( $uid, $password )){
OC_HOOK::emit( "OC_USER", "post_createUser", array( "uid" => $uid, "password" => $password ));
return true;
}
else{
return false;
if( $run ){
//create the user in the first backend that supports creating users
foreach(self::$_usedBackends as $backend){
$result=$backend->createUser($uid,$password);
if($result!==OC_USER_BACKEND_NOT_IMPLEMENTED){
OC_HOOK::emit( "OC_USER", "post_createUser", array( "uid" => $uid, "password" => $password ));
return true;
}
}
}
return false;
}
/**
@ -147,7 +161,11 @@ class OC_USER {
$run = true;
OC_HOOK::emit( "OC_USER", "pre_deleteUser", array( "run" => &$run, "uid" => $uid ));
if( $run && self::$_backend->deleteUser( $uid )){
if( $run ){
//delete the user from all backends
foreach(self::$_usedBackends as $backend){
$backend->deleteUser($uid);
}
// We have to delete the user from all groups
foreach( OC_GROUP::getUserGroups( $uid ) as $i ){
OC_GROUP::removeFromGroup( $uid, $i );
@ -174,7 +192,9 @@ class OC_USER {
$run = true;
OC_HOOK::emit( "OC_USER", "pre_login", array( "run" => &$run, "uid" => $uid ));
if( $run && self::$_backend->login( $uid, $password )){
if( $run && self::checkPassword( $uid, $password )){
$_SESSION['user_id'] = $uid;
OC_LOG::add( "core", $_SESSION['user_id'], "login" );
OC_HOOK::emit( "OC_USER", "post_login", array( "uid" => $uid ));
return true;
}
@ -191,7 +211,9 @@ class OC_USER {
*/
public static function logout(){
OC_HOOK::emit( "OC_USER", "logout", array());
return self::$_backend->logout();
OC_LOG::add( "core", $_SESSION['user_id'], "logout" );
$_SESSION['user_id'] = false;
return true;
}
/**
@ -201,7 +223,12 @@ class OC_USER {
* Checks if the user is logged in
*/
public static function isLoggedIn(){
return self::$_backend->isLoggedIn();
if( isset($_SESSION['user_id']) AND $_SESSION['user_id'] ){
return true;
}
else{
return false;
}
}
/**
@ -211,7 +238,7 @@ class OC_USER {
* generates a password
*/
public static function generatePassword(){
return substr( md5( uniqId().time()), 0, 10 );
return uniqId();
}
/**
@ -226,7 +253,12 @@ class OC_USER {
$run = true;
OC_HOOK::emit( "OC_USER", "pre_setPassword", array( "run" => &$run, "uid" => $uid, "password" => $password ));
if( $run && self::$_backend->setPassword( $uid, $password )){
if( $run ){
foreach(self::$_usedBackends as $backend){
if($backend->userExists($uid)){
$backend->setPassword($uid,$password);
}
}
OC_HOOK::emit( "OC_USER", "post_setPassword", array( "uid" => $uid, "password" => $password ));
return true;
}
@ -244,7 +276,12 @@ class OC_USER {
* Check if the password is correct without logging in the user
*/
public static function checkPassword( $uid, $password ){
return self::$_backend->checkPassword( $uid, $password );
foreach(self::$_usedBackends as $backend){
$result=$backend->checkPassword( $uid, $password );
if($result===true){
return true;
}
}
}
/**
@ -254,6 +291,28 @@ class OC_USER {
* Get a list of all users.
*/
public static function getUsers(){
return self::$_backend->getUsers();
$users=array();
foreach(self::$_usedBackends as $backend){
$result=$backend->getUsers();
if($result!=OC_USER_BACKEND_NOT_IMPLEMENTED){
$users=array_merge($users,$result);
}
}
return $users;
}
/**
* @brief check if a user exists
* @param string $uid the username
* @return boolean
*/
public static function userExists($uid){
foreach(self::$_usedBackends as $backend){
$result=$backend->userExists($uid);
if($result===true){
return true;
}
}
return false;
}
}