From c6efaed5aba9bffa61b91bbcfbadfc2289a1be00 Mon Sep 17 00:00:00 2001 From: Guillaume Viguier Date: Thu, 17 Jun 2010 18:24:44 -0500 Subject: [PATCH] Web services cleanup --- main/webservices/soap.php | 102 +++++++++++ main/webservices/webservice.php | 301 ++++++++++++++++++++++++++++++++ 2 files changed, 403 insertions(+) create mode 100644 main/webservices/soap.php create mode 100644 main/webservices/webservice.php diff --git a/main/webservices/soap.php b/main/webservices/soap.php new file mode 100644 index 0000000000..ad4c6fa5d8 --- /dev/null +++ b/main/webservices/soap.php @@ -0,0 +1,102 @@ +_server = $server; + } + + /** + * Handles the error by sending a SOAP fault through the server + * + * @param WSError Error to handle + */ + public function handle($error) { + $this->_server->fault(strval($error->code), $error->message); + } +} + + +$s = new soap_server(); + +$error_handler = new WSSoapErrorHandler($s); +WSError::setErrorHandler($error_handler); + +// Initialize WSDL support +$s->configureWSDL('WSService', 'urn:WSService'); + +$s->register( + 'WS.test', + array(), + array('return' => 'xsd:string') +); + +$s->register( + 'WS.DisableUser', + array('secret_key' => 'xsd:string', 'user_id_field_name' => 'xsd:string', 'user_id_field_value' => 'xsd:string') +); + +$s->register( + 'WS.EnableUser', + array('secret_key' => 'xsd:string', 'user_id_field_name' => 'xsd:string', 'user_id_field_value' => 'xsd:string') +); + +$s->register( + 'WS.DeleteUser', + array('secret_key' => 'xsd:string', 'user_id_field_name' => 'xsd:string', 'user_id_field_value' => 'xsd:string') +); + +$s->wsdl->addComplexType( + 'extra_field', + 'complexType', + 'struct', + 'all', + '', + array( + 'field_name' => array('name' => 'field_name', 'type' => 'xsd:string'), + 'field_value' => array('name' => 'field_value', 'type' => 'xsd:string') + ) +); + +$s->register( + 'WS.CreateUser', + array( + 'secret_key' => 'xsd:string', + 'firstname' => 'xsd:string', + 'lastname' => 'xsd:string', + 'status' => 'xsd:int', + 'loginname' => 'xsd:string', + 'password' => 'xsd:string', + 'encrypt_method' => 'xsd:string', + 'user_id_field_name' => 'xsd:string', + 'user_id_value' => 'xsd:string', + 'visibility' => 'xsd:int', + 'email' => 'xsd:string', + 'language' => 'xsd:string', + 'phone' => 'xsd:string', + 'expiration_date' => 'xsd:string', + 'extras' => 'tns:extra_field[]' + ), + array('return' => 'xsd:int') +); + +// Use the request to (try to) invoke the service +$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ''; +$s->service($HTTP_RAW_POST_DATA); diff --git a/main/webservices/webservice.php b/main/webservices/webservice.php new file mode 100644 index 0000000000..5a2edf0ac7 --- /dev/null +++ b/main/webservices/webservice.php @@ -0,0 +1,301 @@ +code = $code; + $this->message = $message; + } + + /** + * Sets the error handler + * + * @param WSErrorHandler Error handler + */ + public static function setErrorHandler($handler) { + if($handler instanceof WSErrorHandler) { + self::$_handler = $handler; + } + } + + /** + * Returns the error handler + * + * @return WSErrorHandler Error handler + */ + public static function getErrorHandler() { + return self::$_handler; + } +} + +/** + * Interface that must be implemented by any error handler + */ +interface WSErrorHandler { + /** + * Handle method + * + * @param WSError Error + */ + public function handle($error); +} + +/** + * Main class of the webservice + */ +class WS { + + /** + * Verifies the API key + * + * @param string Secret key + * @return mixed WSError in case of failure, null in case of success + */ + protected function verifyKey($secret_key) { + global $_configuration; + + $security_key = $_SERVER['REMOTE_ADDR'].$_configuration['security_key']; + + if(!api_is_valid_secret_key($secret_key, $security_key)) { + return new WSError(1, "API key is invalid"); + } else { + return null; + } + } + + /** + * Gets the real user id based on the user id field name and value. Note that if the user id field name is "chamilo_user_id", it will use the user id + * in the system database + * + * @param string User id field name + * @param string User id value + * @return mixed System user id if the user was found, WSError otherwise + */ + protected function getUserId($user_id_field_name, $user_id_value) { + if($user_id_field_name == "chamilo_user_id") { + if(UserManager::is_user_id_valid(intval($user_id_value))) { + return intval($user_id_value); + } else { + return new WSError(2, "User was not found"); + } + } else { + $user_id = UserManager::get_user_id_from_original_id($user_id_value, $user_id_field_name); + if($user_id == 0) { + return new WSError(2, "User was not found"); + } else { + return $user_id; + } + } + } + + /** + * Handles an error by calling the WSError error handler + * + * @param WSError Error + */ + protected function handleError($error) { + $handler = WSError::getErrorHandler(); + $handler->handle($error); + } + + /** + * Test function. Returns the string success + * + * @return string Success + */ + public function test() { + return "success"; + } + + /** + * Enables or disables a user + * + * @param string User id field name + * @param string User id value + * @param int Set to 1 to enable and to 0 to disable + */ + protected function changeUserActiveState($user_id_field_name, $user_id_value, $state) { + $user_id = $this->getUserId($user_id_field_name, $user_id_value); + if($user_id instanceof WSError) { + $this->handleError($user_id); + } else { + if($state == 0) { + UserManager::disable($user_id); + } else if($state == 1) { + UserManager::enable($user_id); + } + } + } + + /** + * Disables a user + * + * @param string API secret key + * @param string User id field name. Use "chamilo_user_id" as the field name if you want to use the internal user_id + * @param string User id value + */ + public function DisableUser($secret_key, $user_id_field_name, $user_id_value) { + $verifKey = $this->verifyKey($secret_key); + if($verifKey instanceof WSError) { + // Let the implementation handle it + $this->handleError($verifKey); + } else { + $this->changeUserActiveState($user_id_field_name, $user_id_value, 0); + } + } + + /** + * Enables a user + * + * @param string API secret key + * @param string User id field name. Use "chamilo_user_id" as the field name if you want to use the internal user_id + * @param string User id value + */ + public function EnableUser($secret_key, $user_id_field_name, $user_id_value) { + $verifKey = $this->verifyKey($secret_key); + if($verifKey instanceof WSError) { + $this->handleError($verifKey); + } else { + $this->changeUserActiveState($user_id_field_name, $user_id_value, 1); + } + } + + /** + * Deletes a user + * + * @param string API secret key + * @param string User id field name. Use "chamilo_user_id" as the field name if you want to use the internal user_id + * @param string User id value + */ + public function DeleteUser($secret_key, $user_id_field_name, $user_id_value) { + $verifKey = $this->verifyKey($secret_key); + if($verifKey instanceof WSError) { + $this->handleError($verifKey); + } else { + $user_id = $this->getUserId($user_id_field_name, $user_id_value); + if($user_id instanceof WSError) { + $this->handleError($user_id); + } else { + if(!UserManager::delete_user($user_id)) { + $error = new WSError(3, "There was a problem while deleting this user"); + $this->handleError($error); + } + } + } + } + + /** + * Creates a user (helper method) + * + * @param string User first name + * @param string User last name + * @param int User status + * @param string Login name + * @param string Password (encrypted or not) + * @param string Encrypt method. Leave blank if you are passing the password in clear text, set to the encrypt method used to encrypt the password otherwise. Remember + * to include the salt in the extra fields if you are encrypting the password + * @param string User id field name. Use "chamilo_user_id" as the field name if you want to use the internal user_id + * @param string User id value. Leave blank if you are using the internal user_id + * @param int Visibility. + * @param string User email. + * @param string Language. + * @param string Phone. + * @param string Expiration date + * @param array Extra fields. An array with elements of the form ('field_name' => 'name_of_the_field', 'field_value' => 'value_of_the_field'). + * @return mixed New user id generated by the system, WSError otherwise + */ + protected function createUserHelper($firstname, $lastname, $status, $login, $password, $encrypt_method, $user_id_field_name, $user_id_value, $visibility, $email, $language, $phone, $expiration_date, $extras) { + // Add the original user id field name and value to the extra fields if needed + $extras_associative = array(); + if($user_id_field_name != "chamilo_user_id") { + $extras_associative[$user_id_field_name] = $user_id_value; + } + foreach($extras as $extra) { + $extras_associative[$extra['field_name']] = $extra['field_value']; + } + $result = UserManager::create_user($firstname, $lastname, $status, $email, $login, $password, '', $language, $phone, '', PLATFORM_AUTH_SOURCE, $expiration_date, $visibility, 0, $extras_associative, $encrypt_method); + if($result == false) { + $failure = $api_failureList[0]; + if($failure == 'login-pass already taken') { + return new WSError(4, 'This username is already taken'); + } else if($failure == 'encrypt_method invalid') { + return new WSError(5, 'The encryption of the password is invalid'); + } else { + return new WSError(6, 'There was an error creating the user'); + } + } else { + return $result; + } + } + + /** + * Creates a user + * + * @param string API secret key + * @param string User first name + * @param string User last name + * @param int User status + * @param string Login name + * @param string Password (encrypted or not) + * @param string Encrypt method. Leave blank if you are passing the password in clear text, set to the encrypt method used to encrypt the password otherwise. Remember + * to include the salt in the extra fields if you are encrypting the password + * @param string User id field name. Use "chamilo_user_id" as the field name if you want to use the internal user_id + * @param string User id value. Leave blank if you are using the internal user_id + * @param int Visibility. Set by default to 1 + * @param string User email. Set by default to an empty string + * @param string Language. Set by default to english + * @param string Phone. Set by default to an empty string + * @param string Expiration date. Set to null by default + * @param array Extra fields. An array with elements of the form ('field_name' => 'name_of_the_field', 'field_value' => 'value_of_the_field'). Set to an empty array by default + * @return mixed New user id generated by the system + */ + public function CreateUser($secret_key, $firstname, $lastname, $status, $login, $password, $encrypt_method, $user_id_field_name, $user_id_value, $visibility = 1, $email = '', $language = 'english', $phone = '', $expiration_date = '0000-00-00 00:00:00', $extras = array()) { + // First, verify the secret key + $verifKey = $this->verifyKey($secret_key); + if($verifKey instanceof WSError) { + $this->handleError($verifKey); + } else { + $result = $this->createUserHelper($firstname, $lastname, $status, $login, $password, $encrypt_method, $user_id_field_name, $user_id_value, $visibility, $email, $language, $phone, $expiration_date, $extras); + if($result instanceof WSError) { + $this->handleError($result); + } else { + return $result; + } + } + } + + +} +