Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

Commit df89cc0e authored by Francois Gannaz's avatar Francois Gannaz
Browse files

php code style

parent e2273280
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
/** /**
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3
* @package mod_labnbook
* @copyright 2019 Université Grenoble Alpes * @copyright 2019 Université Grenoble Alpes
*/ */
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
/** /**
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3
* @package mod_labnbook
* @copyright 2019 Université Grenoble Alpes * @copyright 2019 Université Grenoble Alpes
*/ */
...@@ -33,7 +32,8 @@ class environment ...@@ -33,7 +32,8 @@ class environment
*/ */
public $token_exp; public $token_exp;
public function createPayload() : array { public function createPayload(): array
{
$payload = [ $payload = [
'iss' => (int) $this->iss, 'iss' => (int) $this->iss,
'sub' => (int) $this->sub, 'sub' => (int) $this->sub,
......
...@@ -2,15 +2,14 @@ ...@@ -2,15 +2,14 @@
/** /**
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3
* @package mod_labnbook
* @copyright 2019 Université Grenoble Alpes * @copyright 2019 Université Grenoble Alpes
*/ */
namespace mod_labnbook\fetch; namespace mod_labnbook\fetch;
require_once dirname(dirname(__DIR__)) . '/vendor/firebase/php-jwt/src/JWT.php'; require_once \dirname(__DIR__, 2) . '/vendor/firebase/php-jwt/src/JWT.php';
use \Firebase\JWT\JWT; use Firebase\JWT\JWT;
/** /**
* Fetch info from the LabNbook API. * Fetch info from the LabNbook API.
...@@ -41,11 +40,12 @@ class fetcher ...@@ -41,11 +40,12 @@ class fetcher
*/ */
private $lastError; private $lastError;
public function __construct(string $baseUrl, string $secret, environment $environment) { public function __construct(string $baseUrl, string $secret, environment $environment)
{
if (!$secret) { if (!$secret) {
throw new \Exception("The JWT secret key is empty."); throw new \Exception("The JWT secret key is empty.");
} }
$this->baseUrl = rtrim($baseUrl, '/'); $this->baseUrl = \rtrim($baseUrl, '/');
$this->secret = $secret; $this->secret = $secret;
$this->environment = $environment; $this->environment = $environment;
} }
...@@ -53,7 +53,8 @@ class fetcher ...@@ -53,7 +53,8 @@ class fetcher
/** /**
* @return \Stdclass {code, message} * @return \Stdclass {code, message}
*/ */
public function getLastError() : ?\Stdclass { public function getLastError(): ?\Stdclass
{
return (object) $this->lastError; return (object) $this->lastError;
} }
...@@ -65,9 +66,10 @@ class fetcher ...@@ -65,9 +66,10 @@ class fetcher
* @param array $payload Default is empty. Else any assoc array. * @param array $payload Default is empty. Else any assoc array.
* @return mixed * @return mixed
*/ */
public function fetch(string $verb, string $urlPath, array $payload = []) { public function fetch(string $verb, string $urlPath, array $payload = [])
$curl = curl_init(); {
curl_setopt_array($curl, [ $curl = \curl_init();
\curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $verb, CURLOPT_CUSTOMREQUEST => $verb,
CURLOPT_URL => $this->createUrl($urlPath), CURLOPT_URL => $this->createUrl($urlPath),
...@@ -78,32 +80,32 @@ class fetcher ...@@ -78,32 +80,32 @@ class fetcher
], ],
CURLOPT_CONNECTTIMEOUT => self::TIMEOUT, CURLOPT_CONNECTTIMEOUT => self::TIMEOUT,
]); ]);
$response = curl_exec($curl); $response = \curl_exec($curl);
if (curl_errno($curl) !== 0) { if (\curl_errno($curl) !== 0) {
$this->lastError = (object) [ $this->lastError = (object) [
'code' => 0, 'code' => 0,
'message' => curl_error($curl), 'message' => \curl_error($curl),
]; ];
} }
$error = $this->validateResponse($curl, $response); $error = $this->validateResponse($curl, $response);
if ($error) { if ($error) {
curl_close($curl); \curl_close($curl);
error_log("Query $verb $urlPath to labnbook API failed. $error"); \error_log("Query $verb $urlPath to labnbook API failed. $error");
throw new \Exception("HTTP request failed."); throw new \Exception("HTTP request failed.");
} }
// send decoded response? // send decoded response?
$contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE); $contentType = \curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
curl_close($curl); \curl_close($curl);
if ($contentType === 'application/json') { if ($contentType === 'application/json') {
return json_decode($response); return \json_decode($response);
} else {
return $response;
} }
return $response;
} }
public function createUrl(string $urlPath) : string { public function createUrl(string $urlPath): string
return $this->baseUrl . '/' . ltrim($urlPath, '/'); {
return $this->baseUrl . '/' . \ltrim($urlPath, '/');
} }
/** /**
...@@ -114,7 +116,8 @@ class fetcher ...@@ -114,7 +116,8 @@ class fetcher
* @param array $payload Default is empty. Else any assoc array. * @param array $payload Default is empty. Else any assoc array.
* @return string JS source code * @return string JS source code
*/ */
public function getJsFetch(string $verb, string $urlPath, array $payload = []) { public function getJsFetch(string $verb, string $urlPath, array $payload = [])
{
$url = \json_encode($this->createUrl($urlPath)); $url = \json_encode($this->createUrl($urlPath));
$verb = \json_encode($verb); $verb = \json_encode($verb);
$token = $this->encodeJwtToken($urlPath, $payload); $token = $this->encodeJwtToken($urlPath, $payload);
...@@ -134,13 +137,14 @@ fetch($url, { ...@@ -134,13 +137,14 @@ fetch($url, {
EOJS; EOJS;
} }
public function encodeJwtToken(string $urlPath, array $payload) : string { public function encodeJwtToken(string $urlPath, array $payload): string
{
$jwtPayload = $this->environment->createPayload(); $jwtPayload = $this->environment->createPayload();
if ($payload) { if ($payload) {
$jwtPayload['data'] = $payload; $jwtPayload['data'] = $payload;
} }
$jwtPayload['dest'] = '/' . trim($urlPath, '/');; $jwtPayload['dest'] = '/' . \trim($urlPath, '/');
$jwtPayload['iat'] = time(); // UTC timestamp $jwtPayload['iat'] = \time(); // UTC timestamp
return JWT::encode($jwtPayload, $this->secret, 'HS256'); return JWT::encode($jwtPayload, $this->secret, 'HS256');
} }
...@@ -149,15 +153,16 @@ EOJS; ...@@ -149,15 +153,16 @@ EOJS;
* @param resource $response * @param resource $response
* @return string if OK "", else error message * @return string if OK "", else error message
*/ */
protected function validateResponse($curl, $response) { protected function validateResponse($curl, $response)
{
if ($response === false) { if ($response === false) {
$this->lastError = (object) ['message' => "Network error? " . curl_error($curl)]; $this->lastError = (object) ['message' => "Network error? " . \curl_error($curl)];
return "Network error? " . curl_error($curl); return "Network error? " . \curl_error($curl);
} }
$responseCode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); $responseCode = \curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
if ($responseCode != 200) { if ($responseCode != 200) {
$this->lastError = json_decode($response); // Do not verify signature? $this->lastError = \json_decode($response); // Do not verify signature?
if (json_last_error() !== JSON_ERROR_NONE) { if (\json_last_error() !== JSON_ERROR_NONE) {
$this->lastError = (object) ['message' => $response]; $this->lastError = (object) ['message' => $response];
} }
$this->lastError->code = $responseCode; $this->lastError->code = $responseCode;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
/** /**
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3
* @package mod_labnbook
* @copyright 2019 Université Grenoble Alpes * @copyright 2019 Université Grenoble Alpes
*/ */
...@@ -19,15 +18,11 @@ class institution extends moodlefetcher ...@@ -19,15 +18,11 @@ class institution extends moodlefetcher
const ERROR_LOGIN_UNKNOWN = 403; const ERROR_LOGIN_UNKNOWN = 403;
const ERROR_CREATION_FAILED = 500; const ERROR_CREATION_FAILED = 500;
protected function getSigningKey() : string {
global $CFG;
return $CFG->labnbook_api_key;
}
/** /**
* @return int Cf constants: OK, ERROR_* * @return int Cf constants: OK, ERROR_*
*/ */
public function loginUser() : int { public function loginUser(): int
{
try { try {
$this->fetch("POST", "/v1/auth/login"); $this->fetch("POST", "/v1/auth/login");
} catch (\Exception $e) { } catch (\Exception $e) {
...@@ -37,9 +32,10 @@ class institution extends moodlefetcher ...@@ -37,9 +32,10 @@ class institution extends moodlefetcher
return self::OK; return self::OK;
} }
public function createUser($user) { public function createUser($user)
{
try { try {
$this->fetch("PUT", "/v1/user/create", (array)$user); $this->fetch("PUT", "/v1/user/create", (array) $user);
} catch (\Exception $e) { } catch (\Exception $e) {
$error = $this->fetcher->getLastError(); $error = $this->fetcher->getLastError();
return (isset($error->code) ? (int) $error->code : 0); return (isset($error->code) ? (int) $error->code : 0);
...@@ -51,12 +47,13 @@ class institution extends moodlefetcher ...@@ -51,12 +47,13 @@ class institution extends moodlefetcher
/** /**
* Return a JWT token for the redirection page of LnB, so that the user ends on the user-binding page. * Return a JWT token for the redirection page of LnB, so that the user ends on the user-binding page.
* *
* @param string $returnUrl Full URL, including protocol. * @param string $returnUrl full URL, including protocol
* @param string $role "learner" | "teacher" * @param string $role "learner" | "teacher"
* @return string JWT * @return string JWT
* @throws \moodle_exception * @throws \moodle_exception
*/ */
public function getBindingTokenForRedirect(string $returnUrl, string $role) : string { public function getBindingTokenForRedirect(string $returnUrl, string $role): string
{
if ($role !== 'learner' && $role !== 'teacher') { if ($role !== 'learner' && $role !== 'teacher') {
throw new \moodle_exception("Invalid role value in fetch.institution.getBindingToken()"); throw new \moodle_exception("Invalid role value in fetch.institution.getBindingToken()");
} }
...@@ -69,4 +66,10 @@ class institution extends moodlefetcher ...@@ -69,4 +66,10 @@ class institution extends moodlefetcher
]; ];
return $this->fetcher->encodeJwtToken('/v1/redirect', $payload); return $this->fetcher->encodeJwtToken('/v1/redirect', $payload);
} }
protected function getSigningKey(): string
{
global $CFG;
return $CFG->labnbook_api_key;
}
} }
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
/** /**
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3
* @package mod_labnbook
* @copyright 2019 Université Grenoble Alpes * @copyright 2019 Université Grenoble Alpes
*/ */
...@@ -20,7 +19,8 @@ abstract class moodlefetcher ...@@ -20,7 +19,8 @@ abstract class moodlefetcher
*/ */
protected $fetcher; protected $fetcher;
public function __construct() { public function __construct()
{
global $CFG; global $CFG;
$this->fetcher = new fetcher( $this->fetcher = new fetcher(
$CFG->labnbook_api_url, $CFG->labnbook_api_url,
...@@ -29,7 +29,14 @@ abstract class moodlefetcher ...@@ -29,7 +29,14 @@ abstract class moodlefetcher
); );
} }
protected function getEnvironment() : environment { public function getRedirectUrl(): string
{
global $CFG;
return \rtrim($CFG->labnbook_api_url, '/') . '/v1/redirect';
}
protected function getEnvironment(): environment
{
global $CFG, $USER; global $CFG, $USER;
$env = new environment(); $env = new environment();
$env->orig = "inst"; // default value $env->orig = "inst"; // default value
...@@ -38,22 +45,18 @@ abstract class moodlefetcher ...@@ -38,22 +45,18 @@ abstract class moodlefetcher
return $env; return $env;
} }
protected function fetch($verb, $path, $payload = []) { protected function fetch($verb, $path, $payload = [])
{
global $SESSION; global $SESSION;
$response = $this->fetcher->fetch($verb, $path, $payload); $response = $this->fetcher->fetch($verb, $path, $payload);
if (!empty($response->auth)) { if (!empty($response->auth)) {
if (empty($SESSION->labnbook)) { if (empty($SESSION->labnbook)) {
$SESSION->labnbook = new \Stdclass; $SESSION->labnbook = new \Stdclass();
} }
$SESSION->labnbook->auth = $response->auth; $SESSION->labnbook->auth = $response->auth;
} }
return isset($response->data) ? $response->data : $response; return isset($response->data) ? $response->data : $response;
} }
abstract protected function getSigningKey() : string; abstract protected function getSigningKey(): string;
public function getRedirectUrl() : string {
global $CFG;
return rtrim($CFG->labnbook_api_url, '/') . '/v1/redirect';
}
} }
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
/** /**
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU GPL v3
* @package mod_labnbook
* @copyright 2019 Université Grenoble Alpes * @copyright 2019 Université Grenoble Alpes
*/ */
...@@ -20,35 +19,18 @@ class user extends moodlefetcher ...@@ -20,35 +19,18 @@ class user extends moodlefetcher
/** /**
* Check that the current user has a Labnbook authentication, valid for the next 30 s. * Check that the current user has a Labnbook authentication, valid for the next 30 s.
*/ */
public static function isAuthenticated() { public static function isAuthenticated()
{
global $SESSION; global $SESSION;
return !empty($SESSION->labnbook->auth->token_exp) return !empty($SESSION->labnbook->auth->token_exp)
&& $SESSION->labnbook->auth->token_exp > time() + 30; && $SESSION->labnbook->auth->token_exp > \time() + 30;
}
protected function getEnvironment() : environment {
global $SESSION;
if (empty($SESSION->labnbook->auth->token_exp)) {
throw new \Exception("User token for the Labnbook API does not exist.");
}
$env = parent::getEnvironment();
$env->orig = "user";
$env->token_exp = $SESSION->labnbook->auth->token_exp;
return $env;
}
protected function getSigningKey() : string {
global $SESSION;
if (empty($SESSION->labnbook->auth->token)) {
throw new \Exception("User token for the Labnbook API does not exist.");
}
return $SESSION->labnbook->auth->token;
} }
/** /**
* @return array mission[] * @return array mission[]
*/ */
public function getMissions() { public function getMissions()
{
return $this->fetch('GET', '/v1/mission')->data; return $this->fetch('GET', '/v1/mission')->data;
} }
...@@ -62,7 +44,8 @@ class user extends moodlefetcher ...@@ -62,7 +44,8 @@ class user extends moodlefetcher
* @param array $teamconfig * @param array $teamconfig
* @return object teamconfig * @return object teamconfig
*/ */
public function useMission(int $missionId, int $courseId, string $coursename, ?int $groupId = null, array $teamconfig) { public function useMission(int $missionId, int $courseId, string $coursename, ?int $groupId = null, array $teamconfig)
{
return $this return $this
->fetch( ->fetch(
'POST', 'POST',
...@@ -87,7 +70,8 @@ class user extends moodlefetcher ...@@ -87,7 +70,8 @@ class user extends moodlefetcher
* @param array $teamconfig * @param array $teamconfig
* @return object teamconfig * @return object teamconfig
*/ */
public function updateMissionUse(int $missionId, int $courseId, string $coursename, ?int $groupId = null, array $teamconfig) { public function updateMissionUse(int $missionId, int $courseId, string $coursename, ?int $groupId = null, array $teamconfig)
{
return $this return $this
->fetch( ->fetch(
'POST', 'POST',
...@@ -109,7 +93,8 @@ class user extends moodlefetcher ...@@ -109,7 +93,8 @@ class user extends moodlefetcher
* *
* @return string JavaScript Promise * @return string JavaScript Promise
*/ */
public function getJsMissions() { public function getJsMissions()
{
return $this->fetcher->getJsFetch('GET', '/v1/mission') return $this->fetcher->getJsFetch('GET', '/v1/mission')
. '.then(function(r) { . '.then(function(r) {
if (r.ok) { if (r.ok) {
...@@ -128,7 +113,8 @@ class user extends moodlefetcher ...@@ -128,7 +113,8 @@ class user extends moodlefetcher
* @return string JWT * @return string JWT
* @throws \moodle_exception * @throws \moodle_exception
*/ */
public function getReportTokenForRedirect(int $teamconfigId) : string { public function getReportTokenForRedirect(int $teamconfigId): string
{
$payload = [ $payload = [
'path' => "/report/enter/$teamconfigId", 'path' => "/report/enter/$teamconfigId",
]; ];
...@@ -142,7 +128,8 @@ class user extends moodlefetcher ...@@ -142,7 +128,8 @@ class user extends moodlefetcher
* @return string JWT * @return string JWT
* @throws \moodle_exception * @throws \moodle_exception
*/ */
public function getReportsTokenForRedirect(int $teamconfigId) : string { public function getReportsTokenForRedirect(int $teamconfigId): string
{
$payload = [ $payload = [
'path' => "/authoring_tools/lb_reports.php#teamconfig=$teamconfigId", 'path' => "/authoring_tools/lb_reports.php#teamconfig=$teamconfigId",
]; ];
...@@ -156,7 +143,8 @@ class user extends moodlefetcher ...@@ -156,7 +143,8 @@ class user extends moodlefetcher
* @return string JWT * @return string JWT
* @throws \moodle_exception * @throws \moodle_exception
*/ */
public function getTeamingTokenForRedirect(int $teamconfigId) : string { public function getTeamingTokenForRedirect(int $teamconfigId): string
{
$payload = [ $payload = [
'path' => "/authoring_tools/lb_students.php#teamconfig=$teamconfigId", 'path' => "/authoring_tools/lb_students.php#teamconfig=$teamconfigId",
]; ];
...@@ -170,10 +158,32 @@ class user extends moodlefetcher ...@@ -170,10 +158,32 @@ class user extends moodlefetcher
* @return string JWT * @return string JWT
* @throws \moodle_exception * @throws \moodle_exception
*/ */
public function getMissionTokenForRedirect() : string { public function getMissionTokenForRedirect(): string
{
$payload = [ $payload = [
'path' => "/authoring_tools/lb_missions.php", 'path' => "/authoring_tools/lb_missions.php",
]; ];
return $this->fetcher->encodeJwtToken('/v1/redirect', $payload); return $this->fetcher->encodeJwtToken('/v1/redirect', $payload);
} }
protected function getEnvironment(): environment
{
global $SESSION;
if (empty($SESSION->labnbook->auth->token_exp)) {
throw new \Exception("User token for the Labnbook API does not exist.");
}
$env = parent::getEnvironment();
$env->orig = "user";
$env->token_exp = $SESSION->labnbook->auth->token_exp;
return $env;
}
protected function getSigningKey(): string
{
global $SESSION;
if (empty($SESSION->labnbook->auth->token)) {
throw new \Exception("User token for the Labnbook API does not exist.");
}
return $SESSION->labnbook->auth->token;
}
} }