Skip to content

Commit

Permalink
Made fix for REDCap instrument export permission update
Browse files Browse the repository at this point in the history
  • Loading branch information
mullen2 committed Mar 3, 2022
1 parent 3634228 commit 3b248b4
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 10 deletions.
8 changes: 7 additions & 1 deletion RedCapEtlModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,13 @@ public function getDataExportRight()
$dataExportRight = 1; // Full data access
} else {
$rights = $this->getUserRights();
$dataExportRight = $rights['data_export_tool'];
// OLD: $dataExportRight = $rights['data_export_tool'];
$canExport = Authorization::canExportAllInstruments($rights);
if ($canExport) {
$dataExportRight = "1";
} else {
$dataExportRight = "";
}
}
return $dataExportRight;
}
Expand Down
58 changes: 57 additions & 1 deletion classes/Authorization.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,66 @@ public static function hasRedCapUserRightsForEtl($module)

# Users need to have project design permission and "full data set" data export permission
# and not belong to a data access group (DAG)
if ($rights['design'] && $rights['data_export_tool'] == 1 && empty($rights['group_id'])) {
$canExportAllData = false;

# If this is a newer REDCap version that has data export permissions
# specified at the instrument (form) level, check that the user has export
# permission for all instruments.
#
# Example value for data_export_instruments:
# "[enrollment,1][contact_information,1][emergency_contacts,1][weight,1][cardiovascular,1]"
#

if ($rights['design'] && self::canExportAllInstruments($rights) && empty($rights['group_id'])) {
$hasPermission = true;
}
}
return $hasPermission;
}

/**
* Gets individual instrument export rights, if defined.
*
* @param array $rights a user's REDCap project rights.
*/
public static function getInstrumentExportRights($rights)
{
$instrumentExportRights = null;

if (array_key_exists('data_export_instruments', $rights)) {
$dataExportRights = $rights['data_export_rights'];
$dataExportRights = trim($dataExportRights, '[]');
$dataExportRights = explode('][', $dataExportRights);

foreach ($dataExportRights as $dataExportRight) {
$commaIndex = strrpos($dataExportRight, ',');

$instrument = substr($dataExportRight, 0, $commaIndex);
$accessLevel = substr($dataExportRight, $commaIndex + 1);

$instrumentExportRightss[$instrument] = $accessLevel;
}
}
return $instrumentExportRights;
}

public static function canExportAllInstruments($rights)
{
$canExportAllInstruments = false;

if (array_key_exists('data_export_instruments', $rights)) {
$canExportAllInstruments = true;
$instrumentExportRights = self::getInstrumentExportRights($rights);
foreach ($instrumentExportRights as $instrument => $accessLevel) {
if ($accessLevel !== '1') {
$canExportAllInstruments = false;
break;
}
}
} elseif ($rights['data_export_tool'] == 1) {
$canExportAllInstruments = true;
}

return $canExportAllInstruments;
}
}
55 changes: 47 additions & 8 deletions classes/RedCapDb.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function getUserSearchInfo($term)
}

/**
* Gets the projects that that the specified user has permission
* Gets the projects that the specified user has permission
* to access.
*
* @param string username the username whose projects are returned.
Expand All @@ -47,17 +47,45 @@ public function getUserSearchInfo($term)
public function getUserProjects($username)
{
$projects = array();

// OLD CODE (before instrument data export permission change):
//$sql = "select u.username, p.project_id, p.app_title, "
// . " if(u.api_token is null, 0, 1) as has_api_token, u.api_export "
// . ", u.data_export_tool "
// . " from redcap_projects p, redcap_user_rights u "
// . " where u.username = '" . Filter::escapeForMysql($username) . "' "
// . " and p.project_id = u.project_id and p.date_deleted is null" // @codeCoverageIgnore
// ;

$sql = "select u.username, p.project_id, p.app_title, "
. " if(u.api_token is null, 0, 1) as has_api_token, u.api_export "
. ", u.data_export_tool "
. ", u.* "
. " from redcap_projects p, redcap_user_rights u "
. " where u.username = '" . Filter::escapeForMysql($username) . "' "
. " and p.project_id = u.project_id and p.date_deleted is null" // @codeCoverageIgnore
;

$result = db_query($sql);
while ($row = db_fetch_assoc($result)) {
array_push($projects, $row);
$rights = $row;

$projectInfo = array();
$projectInfo['username'] = $row['username'];
$projectInfo['project_id'] = $row['project_id'];
$projectInfo['app_title'] = $row['app_title'];
$projectInfo['has_api_token'] = $row['has_api_token'];
$projectInfo['api_export'] = $row['api_export'];

$canExport = Authorization::canExportAllInstruments($rights);

if ($canExport) {
$projectInfo['data_export_tool'] = "1";
} else {
$projectInfo['data_export_tool'] = "";
}

# array_push($projects, $row);
array_push($projects, $projectInfo);
}
return $projects;
}
Expand All @@ -81,19 +109,30 @@ public function getApiTokens($projectId, $exportRight)
$isExport = false;
$isImport = false;

$sql = "select username, api_token from redcap_user_rights "
# OLD CODE (didn't have data export instruments)
#$sql = "select username, api_token from redcap_user_rights "
# . " where project_id = " . ((int) $projectId) . " "
# . " and api_export = 1 " // @codeCoverageIgnore
# . " and api_token is not null " // @codeCoverageIgnore
# . " and data_export_tool = " . ((int) $exportRight) // @codeCoverageIgnore
# . " and group_id is null" // @codeCoverageIgnore
# ;

$sql = "select * from redcap_user_rights "
. " where project_id = " . ((int) $projectId) . " "
. " and api_export = 1 " // @codeCoverageIgnore
. " and api_token is not null " // @codeCoverageIgnore
. " and data_export_tool = " . ((int) $exportRight) // @codeCoverageIgnore
. " and group_id is null" // @codeCoverageIgnore
;

$queryResult = db_query($sql);
while ($row = db_fetch_assoc($queryResult)) {
$username = $row['username'];
$apiToken = $row['api_token'];
$tokens[$username] = $apiToken;
$rights = $row;
if (Authorization::canExportAllInstruments($rights)) {
$username = $row['username'];
$apiToken = $row['api_token'];
$tokens[$username] = $apiToken;
}
}
return $tokens;
}
Expand Down

0 comments on commit 3b248b4

Please sign in to comment.