Auth.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <?php
  2. /**
  3. *
  4. * @author Christoph Wurst <christoph@owncloud.com>
  5. *
  6. * @license GNU AGPL version 3 or any later version
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Affero General Public License as
  10. * published by the Free Software Foundation, either version 3 of the
  11. * License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. use GuzzleHttp\Client;
  23. use GuzzleHttp\Exception\ClientException;
  24. use GuzzleHttp\Exception\ServerException;
  25. use GuzzleHttp\Cookie\CookieJar;
  26. require __DIR__ . '/../../vendor/autoload.php';
  27. trait Auth {
  28. /** @var string */
  29. private $unrestrictedClientToken;
  30. /** @var string */
  31. private $restrictedClientToken;
  32. /** @var Client */
  33. private $client;
  34. /** @var string */
  35. private $responseXml;
  36. /** @BeforeScenario */
  37. public function setUpScenario() {
  38. $this->client = new Client();
  39. $this->responseXml = '';
  40. $this->cookieJar = new CookieJar();
  41. }
  42. /**
  43. * @When requesting :url with :method
  44. */
  45. public function requestingWith($url, $method) {
  46. $this->sendRequest($url, $method);
  47. }
  48. private function sendRequest($url, $method, $authHeader = null, $useCookies = false) {
  49. $fullUrl = substr($this->baseUrl, 0, -5) . $url;
  50. try {
  51. if ($useCookies) {
  52. $request = $this->client->createRequest($method, $fullUrl, [
  53. 'cookies' => $this->cookieJar,
  54. ]);
  55. } else {
  56. $request = $this->client->createRequest($method, $fullUrl);
  57. }
  58. if ($authHeader) {
  59. $request->setHeader('Authorization', $authHeader);
  60. }
  61. $request->setHeader('OCS_APIREQUEST', 'true');
  62. $request->setHeader('requesttoken', $this->requestToken);
  63. $this->response = $this->client->send($request);
  64. } catch (ClientException $ex) {
  65. $this->response = $ex->getResponse();
  66. } catch (ServerException $ex) {
  67. $this->response = $ex->getResponse();
  68. }
  69. }
  70. /**
  71. * @When the CSRF token is extracted from the previous response
  72. */
  73. public function theCsrfTokenIsExtractedFromThePreviousResponse() {
  74. $this->requestToken = substr(preg_replace('/(.*)data-requesttoken="(.*)">(.*)/sm', '\2', $this->response->getBody()->getContents()), 0, 89);
  75. }
  76. /**
  77. * @param bool $loginViaWeb
  78. * @return object
  79. */
  80. private function createClientToken($loginViaWeb = true) {
  81. if($loginViaWeb) {
  82. $this->loggingInUsingWebAs('user0');
  83. }
  84. $fullUrl = substr($this->baseUrl, 0, -5) . '/index.php/settings/personal/authtokens';
  85. $client = new Client();
  86. $options = [
  87. 'auth' => [
  88. 'user0',
  89. $loginViaWeb ? '123456' : $this->restrictedClientToken,
  90. ],
  91. 'body' => [
  92. 'requesttoken' => $this->requestToken,
  93. 'name' => md5(microtime()),
  94. ],
  95. 'cookies' => $this->cookieJar,
  96. ];
  97. try {
  98. $this->response = $client->send($client->createRequest('POST', $fullUrl, $options));
  99. } catch (\GuzzleHttp\Exception\ServerException $e) {
  100. $this->response = $e->getResponse();
  101. }
  102. return json_decode($this->response->getBody()->getContents());
  103. }
  104. /**
  105. * @Given a new restricted client token is added
  106. */
  107. public function aNewRestrictedClientTokenIsAdded() {
  108. $tokenObj = $this->createClientToken();
  109. $newCreatedTokenId = $tokenObj->deviceToken->id;
  110. $fullUrl = substr($this->baseUrl, 0, -5) . '/index.php/settings/personal/authtokens/' . $newCreatedTokenId;
  111. $client = new Client();
  112. $options = [
  113. 'auth' => ['user0', '123456'],
  114. 'headers' => [
  115. 'requesttoken' => $this->requestToken,
  116. ],
  117. 'json' => [
  118. 'scope' => [
  119. 'filesystem' => false,
  120. ],
  121. ],
  122. 'cookies' => $this->cookieJar,
  123. ];
  124. $this->response = $client->send($client->createRequest('PUT', $fullUrl, $options));
  125. $this->restrictedClientToken = $tokenObj->token;
  126. }
  127. /**
  128. * @Given a new unrestricted client token is added
  129. */
  130. public function aNewUnrestrictedClientTokenIsAdded() {
  131. $this->unrestrictedClientToken = $this->createClientToken()->token;
  132. }
  133. /**
  134. * @When a new unrestricted client token is added using restricted basic token auth
  135. */
  136. public function aNewUnrestrictedClientTokenIsAddedUsingRestrictedBasicTokenAuth() {
  137. $this->createClientToken(false);
  138. }
  139. /**
  140. * @When requesting :url with :method using basic auth
  141. *
  142. * @param string $url
  143. * @param string $method
  144. */
  145. public function requestingWithBasicAuth($url, $method) {
  146. $this->sendRequest($url, $method, 'basic ' . base64_encode('user0:123456'));
  147. }
  148. /**
  149. * @When requesting :url with :method using unrestricted basic token auth
  150. *
  151. * @param string $url
  152. * @param string $method
  153. */
  154. public function requestingWithUnrestrictedBasicTokenAuth($url, $method) {
  155. $this->sendRequest($url, $method, 'basic ' . base64_encode('user0:' . $this->unrestrictedClientToken), true);
  156. }
  157. /**
  158. * @When requesting :url with :method using restricted basic token auth
  159. *
  160. * @param string $url
  161. * @param string $method
  162. */
  163. public function requestingWithRestrictedBasicTokenAuth($url, $method) {
  164. $this->sendRequest($url, $method, 'basic ' . base64_encode('user0:' . $this->restrictedClientToken), true);
  165. }
  166. /**
  167. * @When requesting :url with :method using an unrestricted client token
  168. *
  169. * @param string $url
  170. * @param string $method
  171. */
  172. public function requestingWithUsingAnUnrestrictedClientToken($url, $method) {
  173. $this->sendRequest($url, $method, 'Bearer ' . $this->unrestrictedClientToken);
  174. }
  175. /**
  176. * @When requesting :url with :method using a restricted client token
  177. *
  178. * @param string $url
  179. * @param string $method
  180. */
  181. public function requestingWithUsingARestrictedClientToken($url, $method) {
  182. $this->sendRequest($url, $method, 'Bearer ' . $this->restrictedClientToken);
  183. }
  184. /**
  185. * @When requesting :url with :method using browser session
  186. *
  187. * @param string $url
  188. * @param string $method
  189. */
  190. public function requestingWithBrowserSession($url, $method) {
  191. $this->sendRequest($url, $method, null, true);
  192. }
  193. /**
  194. * @Given a new browser session is started
  195. *
  196. * @param bool $remember
  197. */
  198. public function aNewBrowserSessionIsStarted($remember = false) {
  199. $loginUrl = substr($this->baseUrl, 0, -5) . '/login';
  200. // Request a new session and extract CSRF token
  201. $client = new Client();
  202. $response = $client->get($loginUrl, [
  203. 'cookies' => $this->cookieJar,
  204. ]);
  205. $this->extracRequestTokenFromResponse($response);
  206. // Login and extract new token
  207. $client = new Client();
  208. $response = $client->post(
  209. $loginUrl, [
  210. 'body' => [
  211. 'user' => 'user0',
  212. 'password' => '123456',
  213. 'remember_login' => $remember ? '1' : '0',
  214. 'requesttoken' => $this->requestToken,
  215. ],
  216. 'cookies' => $this->cookieJar,
  217. ]
  218. );
  219. $this->extracRequestTokenFromResponse($response);
  220. }
  221. /**
  222. * @Given a new remembered browser session is started
  223. */
  224. public function aNewRememberedBrowserSessionIsStarted() {
  225. $this->aNewBrowserSessionIsStarted(true);
  226. }
  227. /**
  228. * @Given the cookie jar is reset
  229. */
  230. public function theCookieJarIsReset() {
  231. $this->cookieJar = new CookieJar();
  232. }
  233. /**
  234. * @When the session cookie expires
  235. */
  236. public function whenTheSessionCookieExpires() {
  237. $this->cookieJar->clearSessionCookies();
  238. }
  239. }