├── README.md ├── HEADER.txt ├── net └── xenapi │ └── XenAPI │ └── examples │ ├── php │ ├── HEADER.txt │ ├── example.php │ ├── xen_api.php │ └── LICENSE.txt │ └── dap │ └── plugins │ └── dap_xenapi │ ├── HEADER.txt │ ├── README.txt │ ├── LICENSE.txt │ └── dap_xenapi.class.php └── LICENSE.txt /README.md: -------------------------------------------------------------------------------- 1 | ![Logo](http://i.imgur.com/1qYuVcr.png) 2 | 3 | ========== 4 | 5 | This REST API allows usage of several of XenForo functions, such as authentication, user information and many more functions! 6 | 7 | This project is a WIP, so be patient. Feel free to submit Pull Requests and suggestions. 8 | 9 | Copyright (c) 2012-2014, XenAPI 10 | 11 | XenAPI is licensed under GNU LESSER GENERAL PUBLIC LICENSE Version 3. 12 | -------------------------------------------------------------------------------- /HEADER.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of XenAPI . 3 | * 4 | * XenAPI is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * XenAPI is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ -------------------------------------------------------------------------------- /net/xenapi/XenAPI/examples/php/HEADER.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of XenAPI . 3 | * 4 | * XenAPI is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * XenAPI is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ -------------------------------------------------------------------------------- /net/xenapi/XenAPI/examples/dap/plugins/dap_xenapi/HEADER.txt: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of DAP Xenforo Plugin . 3 | 4 | DAP Xenforo Plugin is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | DAP Xenforo Plugin is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with DAP Xenforo Plugin. If not, see . 16 | */ -------------------------------------------------------------------------------- /net/xenapi/XenAPI/examples/php/example.php: -------------------------------------------------------------------------------- 1 | . 4 | * 5 | * XenAPI is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * XenAPI is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | header('Content-type: text/plain'); 19 | require_once 'xen_api.php'; 20 | 21 | $xenAPI = new XenAPI('http://xenapi.net/api.php', 'REPLACE_THIS_WITH_AN_API_KEY'); 22 | try { 23 | $response = $xenAPI->login('Contex', 'Password', '127.0.0.1'); 24 | var_dump($response); 25 | } catch (Exception $e) { 26 | if ($e->getCode() == 400) { 27 | $error = json_decode($e->getMessage(), TRUE); 28 | die('API call failed: API ERROR CODE=' . $error['error'] . ' & API ERROR MESSAGE=' . $error['message']); 29 | } else { 30 | die('API call failed: HTTP RESPONSE=' . $e->getMessage() . ' & HTTP STATUS CODE=' . $e->getCode()); 31 | } 32 | } -------------------------------------------------------------------------------- /net/xenapi/XenAPI/examples/php/xen_api.php: -------------------------------------------------------------------------------- 1 | . 4 | * 5 | * XenAPI is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * XenAPI is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | class XenAPI 19 | { 20 | const USER_AGENT = 'XenAPI/1.0'; 21 | private $url, $api_key, $method, $parameters = NULL; 22 | private $timeout = 45; 23 | 24 | public function __construct($url, $api_key = NULL) 25 | { 26 | $this->url = $url; 27 | $this->api_key = $api_key; 28 | } 29 | 30 | public function getURL() 31 | { 32 | return $this->url; 33 | } 34 | 35 | public function setURL($url) 36 | { 37 | $this->url = $url; 38 | } 39 | 40 | public function getAPIKey() 41 | { 42 | return $this->api_key; 43 | } 44 | 45 | public function setAPIKey($api_key) 46 | { 47 | $this->api_key = $api_key; 48 | } 49 | 50 | public function getTimeout() 51 | { 52 | return $this->timeout; 53 | } 54 | 55 | public function setTimeout($timeout) 56 | { 57 | $this->timeout = $timeout; 58 | } 59 | 60 | private function setAction($action) 61 | { 62 | $this->setMethod($action); 63 | } 64 | 65 | private function getAction() 66 | { 67 | return $this->getMethod(); 68 | } 69 | 70 | private function setMethod($method) 71 | { 72 | $this->method = $method; 73 | } 74 | 75 | private function getMethod() 76 | { 77 | return $this->method; 78 | } 79 | 80 | private function setParameters(array $parameters) 81 | { 82 | $this->parameters = $parameters; 83 | } 84 | 85 | private function getParameters() 86 | { 87 | return $this->parameters; 88 | } 89 | 90 | private function getAPIURL() 91 | { 92 | return $this->getURL() 93 | . '?action=' . $this->getMethod() 94 | . ($this->getParameters() !== NULL 95 | && is_array($this->getParameters()) 96 | && count($this->getParameters()) > 0 97 | ? '&' . http_build_query($this->getParameters()) 98 | : '' 99 | ); 100 | } 101 | 102 | private function getResponse($url) 103 | { 104 | if (is_callable('curl_init')) { 105 | $ch = curl_init(); 106 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 107 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); 108 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); 109 | curl_setopt($ch, CURLOPT_TIMEOUT, $this->getTimeout()); 110 | curl_setopt($ch, CURLOPT_URL, $url); 111 | curl_setopt($ch, CURLOPT_USERAGENT, self::USER_AGENT); 112 | $result = curl_exec($ch); 113 | $info = curl_getinfo($ch); 114 | if (curl_errno($ch) || $info['http_code'] != 200) { 115 | $error_number = curl_errno($ch); 116 | curl_close($ch); 117 | throw new Exception($result, $info['http_code']); 118 | } else { 119 | curl_close($ch); 120 | return $result; 121 | } 122 | } else { 123 | ini_set('default_socket_timeout', $this->getTimeout()); 124 | $context = stream_context_create(array( 125 | 'http' => array( 126 | 'method' => 'GET', 127 | 'timeout' => $this->getTimeout() 128 | ) 129 | )); 130 | return file_get_contents($url, 0, $context); 131 | } 132 | } 133 | 134 | private function execute() 135 | { 136 | $response = $this->getResponse($this->getAPIURL()); 137 | return json_decode($response, TRUE); 138 | } 139 | 140 | public function authenticate($username, $password) 141 | { 142 | $this->setMethod('authenticate'); 143 | $this->setParameters(array( 144 | 'username' => $username, 145 | 'password' => $password 146 | )); 147 | return $this->execute(); 148 | } 149 | 150 | public function createAlert($user, $cause_user, $content_type, $content_id, $alert_action) 151 | { 152 | $this->setMethod('createAlert'); 153 | $this->setParameters(array( 154 | 'user' => $user, 155 | 'cause_user' => $cause_user, 156 | 'content_type' => $content_type, 157 | 'content_id' => $content_id, 158 | 'alert_action' => $alert_action 159 | )); 160 | return $this->execute(); 161 | } 162 | 163 | public function getActions() 164 | { 165 | $this->setMethod('getActions'); 166 | return $this->execute(); 167 | } 168 | 169 | public function login($username, $password, $ip_address) 170 | { 171 | $this->setMethod('login'); 172 | $this->setParameters(array( 173 | 'username' => $username, 174 | 'password' => $password, 175 | 'ip_address' => $ip_address 176 | )); 177 | $response = $this->execute(); 178 | 179 | $success = setcookie( 180 | $response['cookie_name'], 181 | $response['cookie_id'], 182 | $response['cookie_expiration'], 183 | $response['cookie_path'], 184 | $response['cookie_domain'], 185 | $response['cookie_secure'], 186 | TRUE 187 | ); 188 | 189 | return $success; 190 | } 191 | } 192 | ?> -------------------------------------------------------------------------------- /net/xenapi/XenAPI/examples/dap/plugins/dap_xenapi/README.txt: -------------------------------------------------------------------------------- 1 | === DAP Xenforo Plugin === 2 | License: LGPLv3 or later 3 | License URI: http://www.gnu.org/licenses/lgpl-3.0-standalone.html 4 | Version: 1.0 5 | 6 | DAP Xenforo Plugin allows to automatically register DAP users with a XenForo installation. 7 | 8 | == Description == 9 | 10 | DAP Xenforo Plugin allows to automatically register DAP users with a XenForo installation when they register. 11 | 12 | This is achived by using a XenForo REST API called XenAPI . 13 | 14 | Using XenAPI makes it possible to have DAP and XenForo running on different servers, meaning DAP Xenforo Plugin does not 15 | depend on a local installation of XenForo to function. 16 | 17 | DAP XenForo Plugin send a register request to the XenForo installation via XenAPI to register the user. 18 | In addition, if the group parameter is set, upon the removal of a DAP user; DAP XenForo Plugin sends an additional 19 | request to the XenForo installation via XenAPI. This request moves the XenForo user to a specified XenForo group. 20 | 21 | By default, DAP XenForo Plugin will register the username by using the first name and last name of the user, meaning 22 | the username format of the XenForo user will become `FirstName LastName`, the issue with this is we will have no way to 23 | identify the user if the user changes the username/email in the XenForo installation. 24 | A workaround to this is to use XenForo's custom fields, we can then identify the DAP user with a custom identifier. 25 | The custom identifier uses the following format: `FirstName LastName UserID` 26 | 27 | It is HIGHLY recommend to use a custom field as a unique identifier. 28 | 29 | == Installation == 30 | 31 | Follow each step carefully as they are all crucial for the installation. 32 | 33 | 1. Download XenAPI for Xenforo from the GitHub repository, found here: 34 | https://github.com/Contex/XenAPI/archive/master.zip 35 | 2. Open the downloaded ZIP archive. 36 | 3. Upload `/XenAPI-master/net/xenapi/XenAPI/api.php` to the root directory of your XenForo installation. 37 | 4. Generate a hash by using an online service, like http://www.miraclesalad.com/webtools/md5.php 38 | 5. Set an API key for XenAPI, this can be done by editing the `api.php` file and replacing the `API_KEY` string with 39 | the hash generated in step 4. 40 | 6. Upload `/XenAPI-master/net/xenapi/XenAPI/examples/dap/plugins/dap_xenapi/dap_xenapi.class.php` to 41 | `/plugins/dap_xenapi/` of your DAP installation. 42 | 7. If you are NOT using the group parameter, you can skip this step and continue from step 8. 43 | a. Login to your XenForo Admin panel and go to user groups, `Users -> User Groups -> List User Groups`. 44 | b. Find the group you wish the user to be assigned to when they register. 45 | c. Note the ID of the group, we'll use it later, `admin.php?user-groups/example-group.6/edit`, 6 is the group ID. 46 | 8. If you are NOT using a custom field identifier you can skip this step and continue from step 9. 47 | a. Login to your XenForo Admin panel and go to custom user fields, 48 | `Users -> User Customization -> Custom User Fields`. 49 | b. Press `+ Create New Field` in the upper right hand corner. 50 | c. Set a custom field title, set display location to `Preferences` and set the custom field ID. 51 | Note the ID of the group for the next step, an example of a group ID would be 'unique_user'. 52 | 9. We now need to create the string that is going to be sent to DAP XenForo Plugin. 53 | Here's the the string that is sent to DAP XenForo Plugin: 54 | `dap_xenapi:API_KEY:PROTOCOL:API_LOCATION:GROUP_ID:CUSTOM_FIELD_IDENTIFIER` 55 | 56 | a. `API_KEY` should be replaced with the hash you generated in step 4 and used in step 5. 57 | Example API_KEY: a5b2b1f2mc1mas2f3 58 | b. `PROTOCOL` should be replaced with which protocol you wish to use, current options are only `http` and `https`. 59 | Please note that if you use `http`, the password of the user will be sent over a unecrypted protocol. 60 | Example PROTOCOL: https 61 | c. `API_LOCATION` should be replaced with the location of XenAPI's file, `api.php`, which you should now have in the 62 | root directory of your XenForo installation. Make sure you do NOT include the `http` of the URL. 63 | Example API_LOCATION: example.com/forum/api.php 64 | d. `GROUP_ID` should be replaced with the group ID you wish the user to be assigned to, this is the group ID you 65 | found in step 7. If you wish not to assign the user to a group, you can remove this parameter or set it to `0`. 66 | Example GROUP_ID: 6 67 | Example GRPOU_ID: 0 68 | e. `CUSTOM_FIELD_IDENTIFIER` should be replaced with the field ID you created in step 8. If do not wish to use the 69 | custom field identifier, remove this field. 70 | Example CUSTOM_FIELD_IDENTIFIER: unique_user. 71 | 72 | Examples: 73 | a. Just register the user with the XenForo installation: `dap_xenapi:a5b2b1f2mc1mas2f3:https:example.com/forum/api.php`. 74 | b. Register the user AND assign the user to a specific group: `dap_xenapi:a5b2b1f2mc1mas2f3:https:example.com/forum/api.php:6`. 75 | c. Register the user AND assign the user to a specific group AND use a custom field identifier: `dap_xenapi:a5b2b1f2mc1mas2f3:https:example.com/forum/api.php:6:unique_user`. 76 | d. Register the user AND set a custom field identifier: `dap_xenapi:a5b2b1f2mc1mas2f3:https:example.com/forum/api.php:0:unique_user`. 77 | 78 | It is recommended to use example c. 79 | 10. Open your DAP installation administration and go into product management (Products/Levels -> Manage). 80 | 11. Find the product you wish to integrate XenForo with, click on the `Notifications` tab. 81 | 12. Add the string you created in step 9 to the `Plugin Notification upon User "Add"` 82 | and `Plugin Notification upon User "Add"` fields. 83 | 84 | == Frequently Asked Questions == 85 | 86 | = I need help/support, where can I get it? = 87 | 88 | You can email me at me@contex.me or post a message in the XenAPI thread: http://xenforo.com/community/threads/34270 89 | 90 | = Does this plugin take in count for password changes? = 91 | 92 | Not at this time. 93 | 94 | = Does this plugin take in count for email/username changes? = 95 | 96 | No, but if you use the custom field identifier, you will not run into any issues with the communication between DAP and XenForo. -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. -------------------------------------------------------------------------------- /net/xenapi/XenAPI/examples/php/LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. -------------------------------------------------------------------------------- /net/xenapi/XenAPI/examples/dap/plugins/dap_xenapi/LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. -------------------------------------------------------------------------------- /net/xenapi/XenAPI/examples/dap/plugins/dap_xenapi/dap_xenapi.class.php: -------------------------------------------------------------------------------- 1 | . 4 | 5 | DAP Xenforo Plugin is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | DAP Xenforo Plugin is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with DAP Xenforo Plugin. If not, see . 17 | */ 18 | class dap_xenapi { 19 | const PARAMETERS_FIELDS = 'dap_xenapi:API_KEY:PROTOCOL:API_URL'; 20 | /** 21 | * Default constructor. 22 | */ 23 | function dap_xenapi() 24 | { 25 | } 26 | 27 | /** 28 | * This function is called by DAP once a user registers. 29 | */ 30 | function register($user_id, $product_id, $parameters) 31 | { 32 | // Tell the log that we recieved the request. 33 | $this->log( 34 | 'register', 35 | 'Registering user ID: ' . $user_id . ' with XenAPI.' 36 | ); 37 | 38 | // Grab the DAP user from the user ID. 39 | $dap_user = Dap_User::loadUserById($user_id); 40 | 41 | // Set the unique username. 42 | $username = trim($dap_user->getFirst_name()) 43 | . ' ' . trim($dap_user->getLast_name()); 44 | 45 | // Tell the log that we recieved the request. 46 | $this->log( 47 | 'register', 48 | 'Registering user ID: ' 49 | . $user_id . ' with username "' . $username . '".' 50 | ); 51 | 52 | // Set the variables of the DAP user. 53 | $user_data = array( 54 | 'username' => $username, 55 | 'password' => trim($dap_user->getPassword()), 56 | 'email' => trim($dap_user->getEmail()), 57 | 'user_state' => 'valid', 58 | 'ip_address' => trim($dap_user->getIpaddress()) 59 | ); 60 | 61 | // Split the parameters into an array. 62 | $data = explode(':', $parameters); 63 | 64 | // Initialize the API data. 65 | try 66 | { 67 | $api_data = $this->initializeAPIData($data); 68 | } 69 | catch (Exception $e) 70 | { 71 | // The initilization failed, log error and return exception message. 72 | $this->log('initializeAPIData', $e->getMessage(), 'error'); 73 | return $e->getMessage(); 74 | } 75 | 76 | // Get the additional parameters. 77 | try 78 | { 79 | $additional_parameters = $this->getAdditionalParameters( 80 | $data, 81 | $parameters 82 | ); 83 | } 84 | catch (Exception $e) 85 | { 86 | // The API query failed, log error and return exception message. 87 | $this->log('getAdditionalParameters', $e->getMessage(), 'error'); 88 | return $e->getMessage(); 89 | } 90 | 91 | // Check if the group parameter is set. 92 | if (!empty($additional_parameters['group'])) 93 | { 94 | // Log that we found a custom field identifier. 95 | $this->log( 96 | 'register', 97 | 'Found group: ' . $additional_parameters['group'] 98 | ); 99 | 100 | // Set which group the user should have. 101 | $user_data['add_groups'] = $additional_parameters['group']; 102 | } 103 | 104 | // Check if the custom field identifier parameter is set. 105 | if (!empty($additional_parameters['custom_field_identifier'])) 106 | { 107 | // Log that we found a custom field identifier. 108 | $this->log( 109 | 'register', 110 | 'Found custom field identifier: ' 111 | . $additional_parameters['custom_field_identifier'] 112 | . '=' . $username . ' ' . $user_id 113 | ); 114 | 115 | // Set the custom field identifier. 116 | $user_data['custom_fields'] = $additional_parameters['custom_field_identifier'] 117 | . '=' 118 | . $username . ' ' . $user_id; 119 | } 120 | 121 | // Unset the additional parameters. 122 | unset($additional_parameters); 123 | 124 | // Execute the API query. 125 | try 126 | { 127 | $this->apiRegister( 128 | $api_data['api_url'], 129 | $api_data['api_key'], 130 | $user_data 131 | ); 132 | } 133 | catch (Exception $e) 134 | { 135 | // The API query failed, log error and return exception message. 136 | $this->log('apiRegister', $e->getMessage(), 'error'); 137 | return $e->getMessage(); 138 | } 139 | 140 | return 0; 141 | } 142 | 143 | /** 144 | * This function is called by DAP once a user is removed. 145 | */ 146 | function unregister($user_id, $product_id, $parameters) 147 | { 148 | // Tell the log that we recieved the request. 149 | $this->log( 150 | 'unregister', 151 | 'Editing user ID: ' . $user_id . ' with XenAPI.' 152 | ); 153 | 154 | // Grab the DAP user from the user ID. 155 | $dap_user = Dap_User::loadUserById($user_id); 156 | 157 | // Set the unique username. 158 | $username = trim($dap_user->getFirst_name()) 159 | . ' ' . trim($dap_user->getLast_name()); 160 | 161 | // Set the variables of the DAP user. 162 | $user_data = array( 163 | 'user' => $username 164 | ); 165 | 166 | // Split the parameters into an array. 167 | $data = explode(':', $parameters); 168 | 169 | // Initialize the API data. 170 | try 171 | { 172 | $api_data = $this->initializeAPIData($data); 173 | } 174 | catch (Exception $e) 175 | { 176 | // The initilization failed, log error and return exception message. 177 | $this->log('initializeAPIData', $e->getMessage(), 'error'); 178 | return $e->getMessage(); 179 | } 180 | 181 | // Get the additional parameters. 182 | try 183 | { 184 | $additional_parameters = $this->getAdditionalParameters( 185 | $data, 186 | $parameters 187 | ); 188 | } 189 | catch (Exception $e) 190 | { 191 | // The API query failed, log error and return exception message. 192 | $this->log('getAdditionalParameters', $e->getMessage(), 'error'); 193 | return $e->getMessage(); 194 | } 195 | 196 | // Check if the group parameter is set. 197 | if (!empty($additional_parameters['group'])) 198 | { 199 | // Log that we found a custom field identifier. 200 | $this->log( 201 | 'unregister', 202 | 'Found group: ' . $additional_parameters['group'] 203 | ); 204 | 205 | // Set which group to remove. 206 | $user_data['remove_groups'] = $additional_parameters['group']; 207 | } 208 | 209 | // Check if the custom field identifier parameter is set. 210 | if (!empty($additional_parameters['custom_field_identifier'])) 211 | { 212 | // Log that we found a custom field identifier. 213 | $this->log( 214 | 'unregister', 215 | 'Found custom field identifier: ' 216 | . $additional_parameters['custom_field_identifier'] 217 | ); 218 | 219 | // Set the custom field identifier. 220 | $user_data['custom_field_identifier'] = $additional_parameters['custom_field_identifier']; 221 | } 222 | 223 | // Unset the additional parameters. 224 | unset($additional_parameters); 225 | 226 | // Execute the API query. 227 | try 228 | { 229 | $this->apiEditUser( 230 | $api_data['api_url'], 231 | $api_data['api_key'], 232 | $user_data 233 | ); 234 | } 235 | catch (Exception $e) 236 | { 237 | // The API query failed, log error and return exception message. 238 | $this->log('getResults', $e->getMessage(), 'error'); 239 | return $e->getMessage(); 240 | } 241 | 242 | return 0; 243 | } 244 | 245 | private function handleAPIError($api_response, $api_url, $api_key, $action, 246 | $user_data 247 | ) { 248 | // Decode the JSON. 249 | $api_response = json_decode($api_response, TRUE); 250 | 251 | /* 252 | Check if the JSON decode failed 253 | (meaning that the results was not a JSON string). 254 | */ 255 | if (function_exists('json_last_error')) 256 | { 257 | // PHP version >= 5.3.0 required for json_last_error(). 258 | if (json_last_error() != JSON_ERROR_NONE) 259 | { 260 | // The request failed, throw exception. 261 | $this->log( 262 | 'handleAPIError', 263 | 'Request failed, results was not a JSON string: ' 264 | . $api_response, 265 | 'error' 266 | ); 267 | return NULL; 268 | } 269 | } 270 | else if ($api_response === NULL) 271 | { 272 | // PHP < 5.3.0 workaround for json_last_error(). 273 | // The request failed, throw exception. 274 | $this->log( 275 | 'handleAPIError', 276 | 'Request failed, results was not a JSON string: ' 277 | . $api_response, 278 | 'error' 279 | ); 280 | return NULL; 281 | } 282 | 283 | // Log the error ID and error message. 284 | $this->log( 285 | 'handleAPIError', 286 | 'API returned error id ' . $api_response['error'] . ': ' 287 | . $api_response['message'], 288 | 'error' 289 | ); 290 | 291 | // Check if the error is a user error. 292 | if (!empty($api_response['user_error_id'])) 293 | { 294 | /* 295 | The error was a user error, 296 | log the user error ID and user error message/phrase. 297 | */ 298 | $this->log( 299 | 'handleAPIError', 300 | 'Found user error id ' . $api_response['user_error_id'] . ': ' 301 | . $api_response['user_error_phrase'], 302 | 'error' 303 | ); 304 | 305 | // Check if user already exist. 306 | if ($api_response['user_error_id'] == 40 307 | && !empty($user_data['add_groups']) 308 | ) { 309 | // User exist, let's edit the user instead. 310 | $this->log( 311 | 'handleAPIError', 312 | 'User already exist, attempting to edit user instead.', 313 | 'warning' 314 | ); 315 | 316 | // Init the edit data. 317 | $edit_data = array( 318 | 'user' => $user_data['username'], 319 | 'add_groups' => $user_data['add_groups'] 320 | ); 321 | 322 | // Check if the custom field identifier parameter is set. 323 | if (!empty($user_data['custom_field_identifier'])) 324 | { 325 | // Log that we found a custom field identifier. 326 | $this->log( 327 | 'handleAPIError', 328 | 'Found custom field identifier: ' 329 | . $user_data['custom_field_identifier'] 330 | ); 331 | 332 | // Set the custom field identifier. 333 | $edit_data['custom_field_identifier'] = $user_data['custom_field_identifier']; 334 | } 335 | // Execute the API edit request. 336 | $this->apiEditUser($api_url, $api_key, $edit_data); } 337 | 338 | // Check if the user error field is set. 339 | if (!empty($api_response['user_error_field'])) 340 | { 341 | // User error field is set, log it. 342 | $this->log( 343 | 'handleAPIError', 344 | 'User error field: ' . $api_response['user_error_field'], 345 | 'error' 346 | ); 347 | } 348 | 349 | // Check if the user error key is set. 350 | if (!empty($api_response['user_error_key'])) 351 | { 352 | // User error key is set, log it. 353 | $this->log( 354 | 'handleAPIError', 355 | 'User error key: ' . $api_response['user_error_key'], 356 | 'error' 357 | ); 358 | } 359 | } 360 | } 361 | 362 | private function getAdditionalParameters($data, $parameters) 363 | { 364 | // Init the additional parameters. 365 | $additional_parameters = array(); 366 | 367 | // Check if group parameter is set. 368 | if (isset($data[4])) 369 | { 370 | if (empty($data[4]) && !is_numeric($data[4])) 371 | { 372 | // Group is set but empty, throw error message. 373 | throw Exception( 374 | 'Group ID is empty. Params should be ' 375 | . '(' . self::PARAMETERS_FIELDS . ':GROUP), but is (' 376 | . $parameters . ')' 377 | ); 378 | } 379 | 380 | // Check if group ID is numeric and larger than 0 (we ignore 0). 381 | if (is_numeric($data[4]) && $data[4] > 0) 382 | { 383 | // Set the group. 384 | $additional_parameters['group'] = $data[4]; 385 | } 386 | } 387 | 388 | // Check if the custom identifier field parameter is set. 389 | if (isset($data[5])) 390 | { 391 | if (empty($data[5])) 392 | { 393 | /* 394 | Custom identifier field is set but empty, throw error message. 395 | */ 396 | throw Exception( 397 | 'Custom identifier field is set but empty. Params should be' 398 | . ' (' . self::PARAMETERS_FIELDS 399 | . ':GROUP:CUSTOM_USER_FIELD), but is (' . $parameters . ')' 400 | ); 401 | } 402 | 403 | /* 404 | Set the custom identifier field of 405 | which we want to identify the user with. 406 | */ 407 | $additional_parameters['custom_field_identifier'] = $data[5]; 408 | } 409 | return $additional_parameters; 410 | } 411 | 412 | private function initializeAPIData($data) 413 | { 414 | // Grab the API key from the parameters. 415 | $api_key = $this->getAPIKey($data); 416 | 417 | // Check if we found the API key from the parameters. 418 | if ($api_key == NULL) 419 | { 420 | // Could not find an API key, throw exception. 421 | throw new Exception( 422 | 'Missing API key. Params should be ' 423 | . '(' . self::PARAMETERS_FIELDS 424 | . '), but is (' . $parameters . ')' 425 | ); 426 | } 427 | 428 | // We assume the API key was found. 429 | $this->log('initializeAPIData', 'Found API key = ' . $api_key . '.'); 430 | 431 | // Grab the API key from the parameters. 432 | $api_url = $this->getAPIURL($data); 433 | 434 | // Check if we found the API URL from the parameters. 435 | if ($api_url == NULL) 436 | { 437 | // Could not find an API URL, throw exception. 438 | throw new Exception( 439 | 'Missing API URL. Params should be ' 440 | . '(' . self::PARAMETERS_FIELDS . '), but is (' 441 | . $parameters . ')' 442 | ); 443 | } 444 | 445 | // We assume the API URL was found. 446 | $this->log('initializeAPIData', 'Found API URL = ' . $api_url); 447 | 448 | return array('api_key' => $api_key, 'api_url' => $api_url); 449 | } 450 | 451 | /** 452 | * Get the API key from the intput parameters, 453 | * returns NULL if no API key could be found. 454 | */ 455 | private function getAPIKey($data) 456 | { 457 | if (isset($data[1]) && !empty($data[1])) 458 | { 459 | // We assume the API key was found and return it. 460 | return $data[1]; 461 | } 462 | // An API key could not be found, returning NULL. 463 | return NULL; 464 | } 465 | 466 | /** 467 | * Get the API url from the intput parameters, 468 | * returns NULL if no API url could be found. 469 | */ 470 | private function getAPIURL($data) 471 | { 472 | if (isset($data[2]) && !empty($data[2]) 473 | && isset($data[3]) && !empty($data[3])) 474 | { 475 | // Lowercase the protocol. 476 | $data[2] = strtolower($data[2]); 477 | 478 | // Let's make sure the protocol is correct. 479 | if ($data[2] != 'http' && $data[2] != 'https') 480 | { 481 | // The protocol was invalid, log error and return NULL. 482 | $this->log( 483 | 'getAPIURL', 484 | 'The protocol was invalid, expected "http" or "https",' 485 | . 'but got: ' . $data[2], 486 | 'error' 487 | ); 488 | return NULL; 489 | } 490 | 491 | // We assume the URL key was found and return it. 492 | return strtolower($data[2]) . '://' . $data[3]; 493 | } 494 | // An API URL could not be found, returning NULL. 495 | return NULL; 496 | } 497 | 498 | /** 499 | * Make it easier to log the messages to file. 500 | */ 501 | protected function log($method, $message, $log_level = '') 502 | { 503 | // Set the log prefix. 504 | $log_prefix = 'dap_xenapi.class.php: ' . $method . '(): ' 505 | . (!empty($log_level) ? strtoupper($log_level) . ': ' : '') 506 | . ': '; 507 | 508 | /* 509 | Split the message into an array as 510 | DAP only allows the max length of 200 characters. 511 | */ 512 | $message_array = str_split($message, 200 - strlen($log_prefix)); 513 | 514 | // Loop through the messages and log them. 515 | foreach ($message_array as $message) 516 | { 517 | // Log the message. 518 | logToFile($log_prefix . $message, LOG_INFO_DAP); 519 | } 520 | } 521 | 522 | private function apiRegister($api_url, $api_key, $user_data) 523 | { 524 | $this->getResults($api_url, $api_key, 'register', $user_data); 525 | } 526 | 527 | private function apiEditUser($api_url, $api_key, $user_data) 528 | { 529 | $this->getResults($api_url, $api_key, 'editUser', $user_data); 530 | } 531 | 532 | /** 533 | * This function handles everything related to the XenAPI, 534 | * The function will fallback to file_get_contents if cURL is not found. 535 | * it will either return a JSON string, or NULL if something wrong happend. 536 | */ 537 | private function getResults($api_url = NULL, $api_key = NULL, 538 | $action = NULL, array $user_data 539 | ) { 540 | // Check if all the required parameters have been initialized. 541 | if ($api_url == NULL || $api_key == NULL || $action == NULL) 542 | { 543 | // One of the variables were not initialized, throe exception. 544 | throw new Exception( 545 | 'One or more of the required parameters were NULL. ' 546 | . 'api_key=' . $api_url . ', api_key=' . $api_key 547 | . ', action=' . $action 548 | ); 549 | } 550 | 551 | // Initialize the API data. 552 | $api_data = array( 553 | 'hash' => $api_key, 554 | 'action' => $action 555 | ); 556 | 557 | // Merge the API data array with the user data array. 558 | $api_data = array_merge($user_data, $api_data); 559 | 560 | // Check if cURL is available, fallback to file_get_contents if not. 561 | if (is_callable('curl_init')) 562 | { 563 | // cURL was found avaiable. 564 | $this->log('getResults', 'cURL was found.'); 565 | 566 | // Initialize cURL with the input values. 567 | $curl_handle = curl_init(); 568 | curl_setopt($curl_handle, CURLOPT_URL, $api_url); 569 | curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); 570 | curl_setopt($curl_handle, CURLOPT_POST, 1); 571 | curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $api_data); 572 | 573 | // Grab thet data of the cURL data. 574 | $response = curl_exec($curl_handle); 575 | 576 | // Check if something went wrong with the request. 577 | if ($response === FALSE) 578 | { 579 | // The cURL request failed, throw exception. 580 | throw new Exception( 581 | 'Request failed with action: ' . $action 582 | . ', cURL error: ' . curl_error($curl_handle) 583 | ); 584 | } 585 | 586 | // Get the HTTP status code. 587 | $http_status_code = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE); 588 | 589 | // Close th cURL handle. 590 | curl_close($curl_handle); 591 | 592 | // Check if the status code was 200 (OK). 593 | if ($http_status_code != 200) 594 | { 595 | // Check if the error parameter is set. 596 | if (!empty($response['error'])) 597 | { 598 | $this->handleAPIError( 599 | $response, 600 | $api_url, 601 | $api_key, 602 | $action, 603 | $user_data 604 | ); 605 | } 606 | 607 | /* 608 | The request failed, response header did not return status 200, 609 | throw exception. 610 | */ 611 | throw new Exception( 612 | 'Request failed with action: ' . $action 613 | . ', HTTP status code was not 200: ' . $http_status_code 614 | ); 615 | } 616 | } 617 | else 618 | { 619 | // cURL is not avaiable, fallback to file_get_contents instead. 620 | $this->log( 621 | 'getResults', 622 | 'Could not find cURL, ' 623 | .'falling back to file_get_contents instead', 624 | 'warning' 625 | ); 626 | 627 | // Options for the stream. 628 | $options = array( 629 | 'http' => array( 630 | 'header' => "Content-type: " 631 | . "application/x-www-form-urlencoded\r\n", 632 | 'method' => 'POST', 633 | 'content' => http_build_query($api_data), 634 | ), 635 | ); 636 | 637 | // Create a stream with the options we set above. 638 | $context = stream_context_create($options); 639 | 640 | // Get the results of the API query. 641 | $response = file_get_contents($api_url, FALSE, $context); 642 | 643 | // Check if something went wrong with the request. 644 | if ($response === FALSE) 645 | { 646 | // The request failed, throw exception. 647 | throw new Exception('Request failed with action: ' . $action); 648 | } 649 | 650 | // Check if the status code was 200 (OK). 651 | if (strpos($http_response_header[0], '200') === FALSE) 652 | { 653 | // Check if the error parameter is set. 654 | if (!empty($response['error'])) 655 | { 656 | $this->handleAPIError( 657 | $response, 658 | $api_url, 659 | $api_key, 660 | $action, 661 | $user_data 662 | ); 663 | } 664 | 665 | /* 666 | The request failed, 667 | response header did not return status 200, throw exception. 668 | */ 669 | throw new Exception( 670 | 'Request failed with action: ' . $action 671 | . ', HTTP status code was not 200: ' 672 | . $http_response_header[0] 673 | ); 674 | } 675 | } 676 | /* 677 | For debugging: 678 | $this->log( 679 | 'getResults', 680 | 'Got response from the XenAPI:' . $response . '.' 681 | ); 682 | */ 683 | 684 | // Decode the JSON. 685 | $response_decoded = json_decode($response, TRUE); 686 | 687 | /* 688 | Check if the JSON decode failed 689 | (meaning that the results was not a JSON string). 690 | */ 691 | if (function_exists('json_last_error')) 692 | { 693 | // PHP version >= 5.3.0 required for json_last_error(). 694 | if (json_last_error() != JSON_ERROR_NONE) 695 | { 696 | // The request failed, throw exception. 697 | throw new Exception( 698 | 'Request failed with action: ' . $action 699 | . ', results was not a JSON string: ' . $response 700 | ); 701 | } 702 | } 703 | else if ($response_decoded === NULL) 704 | { 705 | // PHP < 5.3.0 workaround for json_last_error(). 706 | // The request failed, throw exception. 707 | throw new Exception( 708 | 'Request failed with action: ' . $action 709 | . ', results was not a JSON string: ' . $response 710 | ); 711 | } 712 | 713 | /* 714 | The results was a JSON response and contained no errors, 715 | return the results. 716 | */ 717 | return $response_decoded; 718 | } 719 | } 720 | ?> 721 | --------------------------------------------------------------------------------