Skip to content

Commit

Permalink
Compatibility for Lizmap 3.6 & 3.7 - Remove compatibility for 3.5
Browse files Browse the repository at this point in the history
  • Loading branch information
mdouchin committed Jul 23, 2024
1 parent a4c6c25 commit 00f1c2a
Show file tree
Hide file tree
Showing 34 changed files with 18,893 additions and 259 deletions.
4 changes: 2 additions & 2 deletions gobsapi/classes/Indicator.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ public function setDocumentUrl($document)
'gobsapi~indicator:getIndicatorDocument'
);
$document_url = str_replace(
'index.php/gobsapi/indicator/getIndicatorDocument',
'gobsapi.php/gobsapi/indicator/getIndicatorDocument',
'gobsapi.php/project/'.$this->project_key.'/indicator/'.$this->code.'/document/'.$document->uid,
$document_url
);
Expand Down Expand Up @@ -774,7 +774,7 @@ public function setObservationMediaUrl($uid)
'gobsapi~observation:getObservationMedia'
);
$media_url = str_replace(
'index.php/gobsapi/observation/getObservationMedia',
'gobsapi.php/gobsapi/observation/getObservationMedia',
'gobsapi.php/project/'.$this->project_key.'/indicator/'.$this->code.'/observation/'.$uid.'/media',
$media_url
);
Expand Down
71 changes: 40 additions & 31 deletions gobsapi/classes/Project.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public function __construct($project_key, $login)
$this->buildGobsProject();
}
} else {
jLog::log('Project "'.$project_key.'" connection name is not valid: "'.$this->connectionName.'"');
\jLog::log('Project "'.$project_key.'" connection name is not valid: "'.$this->connectionName.'"');
}
}

Expand Down Expand Up @@ -189,14 +189,14 @@ public function checkConnection()
}
} else {
$errorCode = $cnx->errorCode();
jLog::log('Connection to the PostgreSQL service "'.$this->connectionName.'" failed', 'error');
jLog::log($errorCode, 'error');
\jLog::log('Connection to the PostgreSQL service "'.$this->connectionName.'" failed', 'error');
\jLog::log($errorCode, 'error');
$status = false;
}
} catch (Exception $e) {
$msg = $e->getMessage();
jLog::log('Connection to the PostgreSQL service "'.$this->connectionName.'" failed', 'error');
jLog::log($msg, 'error');
\jLog::log('Connection to the PostgreSQL service "'.$this->connectionName.'" failed', 'error');
\jLog::log($msg, 'error');
$status = false;
}

Expand All @@ -217,14 +217,15 @@ public function checkConnection()
public function getProjectPropertiesFromDatabase()
{
$project = null;

$cnx = jDb::getConnection($this->connectionProfile);
$projectCode = $this->project_key;
$groups = implode('@@', $this->userGroups);
$sql = "
WITH
proj AS (
SELECT id
FROM gobs.project
WHERE pt_code = $1
WHERE pt_code = ".$cnx->quote($projectCode)."
LIMIT 1
),
global_view AS (
Expand All @@ -241,11 +242,11 @@ public function getProjectPropertiesFromDatabase()
SELECT
fk_id_project,
string_agg(pv_label, ',') AS labels,
ST_multi(ST_Union(geom))::geometry(MULTIPOLYGON, 4326) AS geom
CAST( ST_multi(ST_Union(geom)) AS geometry(MULTIPOLYGON, 4326) ) AS geom
FROM proj, gobs.project_view AS pv
WHERE fk_id_project = proj.id
AND regexp_split_to_array(pv_groups, '[\\s,;]+')
&& regexp_split_to_array($2, '@@')
&& regexp_split_to_array(".$cnx->quote($groups).", '@@')
GROUP BY fk_id_project
)
SELECT
Expand All @@ -263,37 +264,45 @@ public function getProjectPropertiesFromDatabase()
INNER JOIN merged_views AS mv
ON mv.fk_id_project = p.id
WHERE p.pt_code = $1
WHERE p.pt_code = ".$cnx->quote($projectCode)."
LIMIT 1
";
$params = array(
$this->project_key,
implode('@@', $this->userGroups),
);

$resultset = null;
try {

$resultset = $cnx->prepare($sql);
$resultset->execute($params);
// We do not used prepared statement anymore because this feature seems broken
$execute = $resultset->execute();

$data = array();
foreach ($resultset->fetchAll() as $record) {
$data['id'] = $record->id;
$data['code'] = $record->pt_code;
$data['lizmap_project_key'] = $record->pt_lizmap_project_key;
$data['label'] = $record->pt_label;
$data['description'] = $record->pt_description;
$data['indicator_codes'] = $record->pt_indicator_codes;
$data['allowed_polygon_wkt'] = $record->allowed_polygon_wkt;
$data['xmin'] = $record->xmin;
$data['ymin'] = $record->ymin;
$data['xmax'] = $record->xmax;
$data['ymax'] = $record->ymax;
if ($resultset && $resultset->id() === false) {
$errorCode = $cnx->errorCode();

throw new Exception($errorCode);
}

if ($resultset !== null) {
foreach ($resultset->fetchAll() as $record) {
$data['id'] = $record->id;
$data['code'] = $record->pt_code;
$data['lizmap_project_key'] = $record->pt_lizmap_project_key;
$data['label'] = $record->pt_label;
$data['description'] = $record->pt_description;
$data['indicator_codes'] = $record->pt_indicator_codes;
$data['allowed_polygon_wkt'] = $record->allowed_polygon_wkt;
$data['xmin'] = $record->xmin;
$data['ymin'] = $record->ymin;
$data['xmax'] = $record->xmax;
$data['ymax'] = $record->ymax;
}
}

return $data;
} catch (Exception $e) {
$msg = $e->getMessage();
jLog::log('An error occured while requesting the properties for the project "'.$this->project_key.'"', 'error');
jLog::log($msg, 'error');
\jLog::log('An error occurred while requesting the properties for the project "'.$this->project_key.'"', 'error');
\jLog::log($msg, 'error');

return null;
}
Expand Down Expand Up @@ -327,7 +336,7 @@ private function buildGobsProject()
'gobsapi~project:getProjectGeopackage',
);
$gpkg_url = str_replace(
'index.php/gobsapi/project/getProjectGeopackage',
'gobsapi.php/gobsapi/project/getProjectGeopackage',
'gobsapi.php/project/'.$this->project_key.'/geopackage',
$gpkg_url
);
Expand All @@ -345,7 +354,7 @@ private function buildGobsProject()
'gobsapi~project:getProjectIllustration',
);
$media_url = str_replace(
'index.php/gobsapi/project/getProjectIllustration',
'gobsapi.php/gobsapi/project/getProjectIllustration',
'gobsapi.php/project/'.$this->project_key.'/illustration',
$media_url
);
Expand Down
143 changes: 143 additions & 0 deletions gobsapi/classes/gobsapiListener.listener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?php
/**
* @package lizmap
* @subpackage gobsapi
* @author 3liz
* @copyright 2020 3liz
* @link http://3liz.com
* @license All rights reserved
*/

class gobsapiListenerListener extends \jEventListener {

/**
* @param \jEvent $event
*/
function onAuthLogin($event) {
/** @var samlAuthDriver $driver */
$driver = \jAuth::getDriver();
if (get_class($driver) != 'samlAuthDriver') {
return;
}

$attributes = $driver->getSAMLAttributes();
\jLog::dump($attributes, "onAuthLogin: SAML attributes");


$allGroups = array();
foreach(jAcl2DbUserGroup::getGroupList() as $group) {
$allGroups[$group->id_aclgrp] = $group;
}

$login = $event->login;

$groupsOfUser = array();
if (isset($attributes['GOBS_ROLE'])) {
// expect to have array having this kind of item:
// '{"id":"cn=ROLE_GOBS_ADMIN,ou=ROLE,cn=GOBS,ou=application,dc=pacte,dc=projet", "code":"ROLE_GOBS_ADMIN", "label":"Role admin pour G-Obs"}'

if (!is_array($attributes['GOBS_ROLE'])) {
$attributes['GOBS_ROLE'] = array($attributes['GOBS_ROLE']);
}

$groupsOfUser = $this->registerGroups($allGroups, $attributes['GOBS_ROLE'], 'GOBS_ROLE');
}

if (isset($attributes['GOBS_SI'])) {
// expect to have array having this kind of item:
// '{"id":null, "code":"GOBS_ADMIN", "label":"Administrateurs G-Obs", "description":"Les adminstrateurs de G-Obs"}'
if (!is_array($attributes['GOBS_SI'])) {
$attributes['GOBS_SI'] = array($attributes['GOBS_SI']);
}

$groupsOfUser = array_merge($groupsOfUser, $this->registerGroups($allGroups, $attributes['GOBS_SI'], 'GOBS_SI'));
}

\jLog::dump(array_keys($groupsOfUser), "onAuthLogin: Groupes de l'utilisateur $login");
$groupToRemove = array();
foreach(jAcl2DbUserGroup::getGroupList($login) as $group) {
if ($group->grouptype == 2) {
// private group, let's ignore
continue;
}
if (isset($groupsOfUser[$group->id_aclgrp])) {
// the user is already in the group
unset($groupsOfUser[$group->id_aclgrp]);
}
else {
// the user is in a group that is not listed in roles given by SAML
// let's remove him from it
$groupToRemove[] = $group->id_aclgrp;
}
}

$hasChanges = false;
foreach($groupToRemove as $grpId) {
\jLog::log("onAuthLogin: Remove $login from $grpId");
\jAcl2DbUserGroup::removeUserFromGroup($login, $grpId);
$hasChanges = true;
}

foreach($groupsOfUser as $grpId => $ok) {
\jLog::log("onAuthLogin: Add $login into $grpId");
\jAcl2DbUserGroup::addUserToGroup($login, $grpId);
$hasChanges = true;
}

if ($hasChanges) {
\jAcl2::clearCache();
}
}

protected function registerGroups(&$allGroups, $samlGroups, $rolesName) {
$groupsOfUser = array();
$adminGroup = array();
if (isset(jApp::config()->gobsapi['adminSAMLGobsRoleName'])) {
$adminGroup = \jApp::config()->gobsapi['adminSAMLGobsRoleName'];
if (!is_array($adminGroup)) {
$adminGroup = array($adminGroup);
}
}

foreach($samlGroups as $roleAsJson) {
$role = @json_decode($roleAsJson, true);
if (!$role || !isset($role['code']) || $role['code'] == '') {
\jLog::log('gobs login: bad role value into '.$rolesName.', not a json or code property missing: '.$roleAsJson, 'error');
continue;
}
$idGrp = $role['code'];
$name = isset($role['label']) ? $role['label']: $idGrp;
if ($name == '') {
$name = $idGrp;
}
if (!isset($allGroups[$idGrp])) {
\jAcl2DbUserGroup::createGroup($name, $idGrp);
if (in_array($idGrp, $adminGroup)) {
foreach(jAcl2DbManager::$ACL_ADMIN_RIGHTS as $role) {
\jAcl2DbManager::addRight($idGrp, $role);
}
\jAcl2DbManager::addRight($idGrp, 'acl.group.create');
\jAcl2DbManager::addRight($idGrp, 'auth.users.list');
\jAcl2DbManager::addRight($idGrp, 'auth.users.modify');
\jAcl2DbManager::addRight($idGrp, 'auth.users.view');
\jAcl2DbManager::addRight($idGrp, 'lizmap.admin.access');
\jAcl2DbManager::addRight($idGrp, 'lizmap.admin.repositories.create');
\jAcl2DbManager::addRight($idGrp, 'lizmap.admin.repositories.delete');
\jAcl2DbManager::addRight($idGrp, 'lizmap.admin.repositories.update');
\jAcl2DbManager::addRight($idGrp, 'lizmap.admin.repositories.view');
\jAcl2DbManager::addRight($idGrp, 'lizmap.admin.services.update');
\jAcl2DbManager::addRight($idGrp, 'lizmap.admin.services.view');

}
\jAcl2DbManager::removeRight($idGrp, 'auth.user.change.password', '-', true);
\jAcl2DbManager::removeRight($idGrp, 'auth.users.change.password', '-', true);
\jAcl2DbManager::addRight($idGrp, 'auth.user.view');
\jAcl2DbManager::addRight($idGrp, 'auth.user.modify');
}

$groupsOfUser[$idGrp] = true;
}
return $groupsOfUser;
}

}
11 changes: 10 additions & 1 deletion gobsapi/controllers/observation.classic.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,17 @@ private function checkBodyActions($from)
{
// Parameters
$body = $this->request->readHttpBody();
// Since Jelix 1.7, the body is given as an array and not as a string anymore.
// Gobs Observation class expects it as a JSON string
if (is_array($body)) {
// For new versions, we must re-encode it as JSON
$bodyString = json_encode($body);
} else {
$bodyString = $body;
}

$observation_uid = null;
$gobs_observation = new Observation($this->user, $this->indicator, $observation_uid, $body);
$gobs_observation = new Observation($this->user, $this->indicator, $observation_uid, $bodyString);

// Check observation JSON
$action = 'create';
Expand Down
6 changes: 2 additions & 4 deletions gobsapi/events.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<events xmlns="http://jelix.org/ns/events/1.0">
<!--
<listener name="gobsapi">
<event name="mapDockable" />
<listener name="gobsapiListener">
<event name="AuthLogin" />
</listener>
-->
</events>
File renamed without changes.
Loading

0 comments on commit 00f1c2a

Please sign in to comment.