Skip to content

Commit

Permalink
add mem_uuid and csrf token check for membership change
Browse files Browse the repository at this point in the history
  • Loading branch information
Fasse committed Oct 19, 2021
1 parent 3225d93 commit 87f304f
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 84 deletions.
2 changes: 2 additions & 0 deletions adm_program/installation/db_scripts/db.sql
Expand Up @@ -348,6 +348,7 @@ CREATE TABLE %PREFIX%_members
mem_id integer unsigned NOT NULL AUTO_INCREMENT,
mem_rol_id integer unsigned NOT NULL,
mem_usr_id integer unsigned NOT NULL,
mem_uuid varchar(36) NOT NULL,
mem_begin date NOT NULL,
mem_end date NOT NULL DEFAULT '9999-12-31',
mem_leader boolean NOT NULL DEFAULT '0',
Expand All @@ -365,6 +366,7 @@ DEFAULT character SET = utf8
COLLATE = utf8_unicode_ci;

CREATE INDEX %PREFIX%_idx_mem_rol_usr_id ON %PREFIX%_members (mem_rol_id, mem_usr_id);
CREATE UNIQUE INDEX %PREFIX%_idx_mem_uuid ON %PREFIX%_members (mem_uuid);

/*==============================================================*/
/* Table: adm_menu */
Expand Down
3 changes: 3 additions & 0 deletions adm_program/installation/db_scripts/update_4_1.xml
Expand Up @@ -70,6 +70,7 @@
<step id="335">ALTER TABLE %PREFIX%_rooms ADD COLUMN room_uuid varchar(36)</step>
<step id="340">ALTER TABLE %PREFIX%_user_fields ADD COLUMN usf_uuid varchar(36)</step>
<step id="350">ALTER TABLE %PREFIX%_user_relation_types ADD COLUMN urt_uuid varchar(36)</step>
<step id="360">ALTER TABLE %PREFIX%_members ADD COLUMN mem_uuid varchar(36)</step>
<step id="400">ComponentUpdateSteps::updateStep41AddUuid</step>
<step id="410" database="mysql">ALTER TABLE %PREFIX%_users MODIFY COLUMN usr_uuid varchar(36) NOT NULL</step>
<step id="420">CREATE UNIQUE INDEX %PREFIX%_idx_usr_uuid ON %PREFIX%_users (usr_uuid)</step>
Expand Down Expand Up @@ -109,5 +110,7 @@
<step id="760">CREATE UNIQUE INDEX %PREFIX%_idx_urt_uuid ON %PREFIX%_user_relation_types (urt_uuid)</step>
<step id="770" database="mysql">ALTER TABLE %PREFIX%_roles MODIFY COLUMN rol_name varchar(100)</step>
<step id="780" database="pgsql">ALTER TABLE %PREFIX%_roles ALTER COLUMN rol_name TYPE varchar(100)</step>
<step id="790" database="mysql">ALTER TABLE %PREFIX%_members MODIFY COLUMN mem_uuid varchar(36) NOT NULL</step>
<step id="800">CREATE UNIQUE INDEX %PREFIX%_idx_mem_uuid ON %PREFIX%_members (mem_uuid)</step>
<step>stop</step>
</update>
14 changes: 7 additions & 7 deletions adm_program/modules/profile/profile.js
Expand Up @@ -26,7 +26,7 @@ function ProfileJS(gRootPath) {
$(".admMemberInfo").click(function() {
showHideMembershipInformation($(this));
});
formSubmitEvent();
formSubmitEvent('#profile_roles_box_body');
}
});
};
Expand All @@ -37,7 +37,7 @@ function ProfileJS(gRootPath) {
dataType: "html",
success: function(responseText) {
$("#profile_former_roles_box_body").html(responseText);
formSubmitEvent();
formSubmitEvent('#profile_former_roles_box_body');
}
}
);
Expand All @@ -49,7 +49,7 @@ function ProfileJS(gRootPath) {
dataType: "html",
success: function(responseText) {
$("#profile_future_roles_box_body").html(responseText);
formSubmitEvent();
formSubmitEvent('#profile_future_roles_box_body');
}
}
);
Expand All @@ -74,11 +74,11 @@ function ProfileJS(gRootPath) {
return "leader-" + number;
}

this.toggleDetailsOn = function (memberId) {
$("#membership_period_" + memberId).css({"visibility": "visible", "display": "block"});
this.toggleDetailsOn = function (memberUuid) {
$("#membership_period_" + memberUuid).css({"visibility": "visible", "display": "block"});
};

this.toggleDetailsOff = function (memberId) {
$("#membership_period_" + memberId).css({"visibility": "hidden", "display": "none"});
this.toggleDetailsOff = function (memberUuid) {
$("#membership_period_" + memberUuid).css({"visibility": "hidden", "display": "none"});
};
}
36 changes: 19 additions & 17 deletions adm_program/modules/profile/profile.php
Expand Up @@ -149,40 +149,42 @@ function callbackFutureRoles() {
}
}
function formSubmitEvent() {
$(".button-membership-period-form").click(function(event) {
var memberId = $(this).attr("data-admidio");
var dateStart = $("#membership_start_date_" + memberId).val();
var dateEnd = $("#membership_end_date_" + memberId).val();
var action = $("#membership_period_form_" + memberId).attr("action") + "&membership_start_date_" + memberId + "=" + dateStart + "&membership_end_date_" + memberId + "=" + dateEnd;
var formAlert = $("#membership_period_form_" + memberId + " .form-alert");
function formSubmitEvent(rolesAreaId = "") {
$(rolesAreaId + " .admidio-form-membership-period").submit(function(event) {
var memberUuid = $(this).attr("data-admidio");
var formAlert = $("#membership_period_form_" + memberUuid + " .form-alert");
event.preventDefault(); // avoid to execute the actual submit of the form.
formAlert.hide();
$.get({
url: action,
success: function(data) {
$.post({
url: $(this).attr("action"),
data: $(this).serialize(),
success: function(data)
{
if (data === "success") {
formAlert.attr("class", "alert alert-success form-alert");
formAlert.html("<i class=\"fas fa-check\"></i><strong>'.$gL10n->get('SYS_SAVE_DATA').'</strong>");
formAlert.fadeIn("slow");
formAlert.animate({opacity: 1.0}, 2500);
formAlert.animate({opacity: 1.0}, 5000);
formAlert.fadeOut("slow");
var membershipPeriod = $("#membership_period_" + memberId);
membershipPeriod.animate({opacity: 1.0}, 2500);
var membershipPeriod = $("#membership_period_" + memberUuid);
membershipPeriod.animate({opacity: 1.0}, 5000);
membershipPeriod.fadeOut("slow");
profileJS.reloadRoleMemberships();
profileJS.reloadFormerRoleMemberships();
profileJS.reloadFutureRoleMemberships();
formSubmitEvent();
} else {
formAlert.attr("class", "alert alert-danger form-alert");
formAlert.fadeIn();
formAlert.html("<i class=\"fas fa-exclamation-circle\"></i>" + data);
}
}
});
});
return false;
});
}
');
Expand All @@ -201,6 +203,7 @@ function formSubmitEvent() {
todayHighlight: true,
autoclose: true
});
formSubmitEvent();',
true
);
Expand Down Expand Up @@ -709,11 +712,10 @@ function formSubmitEvent() {
// Roles block
// *******************************************************************************

// Alle Rollen auflisten, die dem Mitglied zugeordnet sind
// List all roles assigned to the member
$roleStatement = getRolesFromDatabase($userId);
$countRole = $roleStatement->rowCount();

// Ausgabe
$page->addHtml('
<div class="card admidio-field-group" id="profile_roles_box">
<div class="card-header">'.$gL10n->get('SYS_ROLE_MEMBERSHIPS'));
Expand Down
48 changes: 25 additions & 23 deletions adm_program/modules/profile/profile_function.php
Expand Up @@ -17,29 +17,26 @@
* 6 - reload future role memberships
* 7 - save membership data
* 8 - Export vCard of role
* user_uuid : UUID of the user to be edited
* mem_id : Id of role membership to should be edited
* role_uuid : UUID of role from which the user vcards should be exported
* user_uuid : UUID of the user to be edited
* member_uuid : UUID of role membership that should be edited
* role_uuid : UUID of role from which the user vcards should be exported
***********************************************************************************************
*/
require_once(__DIR__ . '/../../system/common.php');
require_once(__DIR__ . '/roles_functions.php');
require(__DIR__ . '/../../system/login_valid.php');

// Initialize and check the parameters
$getUserUuid = admFuncVariableIsValid($_GET, 'user_uuid', 'string');
$getRoleUuid = admFuncVariableIsValid($_GET, 'role_uuid', 'string');
$getMemberId = admFuncVariableIsValid($_GET, 'mem_id', 'int');
$getMode = admFuncVariableIsValid($_GET, 'mode', 'int');
$getUserUuid = admFuncVariableIsValid($_GET, 'user_uuid', 'string');
$getRoleUuid = admFuncVariableIsValid($_GET, 'role_uuid', 'string');
$getMemberUuid = admFuncVariableIsValid($_GET, 'member_uuid','string');
$getMode = admFuncVariableIsValid($_GET, 'mode', 'int');

// in ajax mode only return simple text on error
if($getMode === 7)
{
$gMessage->showHtmlTextOnly(true);
}

if(in_array($getMode, array(2, 3))) {
if(in_array($getMode, array(2, 3, 7))) {
try {
// in ajax mode only return simple text on error
$gMessage->showHtmlTextOnly(true);

// check the CSRF token of the form against the session token
SecurityUtils::validateCsrfToken($_POST['admidio-csrf-token']);
} catch (AdmException $exception) {
Expand Down Expand Up @@ -73,7 +70,8 @@
elseif($getMode === 2)
{
// Cancel membership of role
$member = new TableMembers($gDb, $getMemberId);
$member = new TableMembers($gDb);
$member->readDataByUuid($getMemberUuid);
$role = new TableRoles($gDb, (int) $member->getValue('mem_rol_id'));

// if user has the right then cancel membership
Expand Down Expand Up @@ -102,7 +100,8 @@
// Remove former membership of role
if($gCurrentUser->isAdministrator())
{
$member = new TableMembers($gDb, $getMemberId);
$member = new TableMembers($gDb);
$member->readDataByUuid($getMemberUuid);
$member->delete();

// Entfernen erfolgreich -> Rueckgabe fuer XMLHttpRequest
Expand Down Expand Up @@ -150,11 +149,14 @@
}
elseif($getMode === 7)
{
$gLogger->error('::test::');
$gLogger->error(print_r($_POST, true));
// save membership date changes
$getMembershipStart = admFuncVariableIsValid($_GET, 'membership_start_date_'.$getMemberId, 'date', array('requireValue' => true));
$getMembershipEnd = admFuncVariableIsValid($_GET, 'membership_end_date_'.$getMemberId, 'date', array('requireValue' => true));
$postMembershipStart = admFuncVariableIsValid($_POST, 'membership_start_date_'.$getMemberUuid, 'date', array('requireValue' => true));
$postMembershipEnd = admFuncVariableIsValid($_POST, 'membership_end_date_'.$getMemberUuid, 'date', array('requireValue' => true));

$member = new TableMembers($gDb, $getMemberId);
$member = new TableMembers($gDb);
$member->readDataByUuid($getMemberUuid);
$role = new TableRoles($gDb, (int) $member->getValue('mem_rol_id'));

// check if user has the right to edit this membership
Expand All @@ -167,7 +169,7 @@
$formatedEndDate = '';

// Check das Beginn Datum
$startDate = \DateTime::createFromFormat($gSettingsManager->getString('system_date'), $getMembershipStart);
$startDate = \DateTime::createFromFormat($gSettingsManager->getString('system_date'), $postMembershipStart);
if($startDate === false)
{
exit($gL10n->get('SYS_DATE_INVALID', array($gL10n->get('SYS_START'), $gSettingsManager->getString('system_date'))));
Expand All @@ -179,9 +181,9 @@
}

// Falls gesetzt wird das Enddatum gecheckt
if($getMembershipEnd !== '')
if($postMembershipEnd !== '')
{
$endDate = \DateTime::createFromFormat($gSettingsManager->getString('system_date'), $getMembershipEnd);
$endDate = \DateTime::createFromFormat($gSettingsManager->getString('system_date'), $postMembershipEnd);
if($endDate === false)
{
exit($gL10n->get('SYS_DATE_INVALID', array($gL10n->get('SYS_END'), $gSettingsManager->getString('system_date'))));
Expand All @@ -204,7 +206,7 @@
}

// save role membership
$user->editRoleMembership($getMemberId, $formatedStartDate, $formatedEndDate);
$user->editRoleMembership($member->getValue('mem_id'), $formatedStartDate, $formatedEndDate);

echo 'success';
}
Expand Down
33 changes: 18 additions & 15 deletions adm_program/modules/profile/roles_functions.php
Expand Up @@ -138,7 +138,7 @@ function getRoleMemberships($htmlListId, User $user, \PDOStatement $roleStatemen
$deleteMode = 'pro_future';
}

$memberId = (int) $member->getValue('mem_id');
$memberUuid = $member->getValue('mem_uuid');

// create list entry for one role
$roleMemHTML .= '
Expand All @@ -163,7 +163,8 @@ function getRoleMemberships($htmlListId, User $user, \PDOStatement $roleStatemen

$roleMemHTML .= '&nbsp;
</span>
<span class="float-right text-right">';
<span class="float-right text-right">
<span class="mr-2">';
if($showRoleEndDate)
{
$roleMemHTML .= $gL10n->get('SYS_SINCE_TO', array($member->getValue('mem_begin', $gSettingsManager->getString('system_date')), $member->getValue('mem_end', $gSettingsManager->getString('system_date'))));
Expand All @@ -176,59 +177,61 @@ function getRoleMemberships($htmlListId, User $user, \PDOStatement $roleStatemen
{
$roleMemHTML .= $gL10n->get('SYS_SINCE', array($member->getValue('mem_begin', $gSettingsManager->getString('system_date'))));
}
$roleMemHTML .= '</span>';

if($role->allowedToAssignMembers($gCurrentUser))
{
// do not edit administrator role
if ($row['rol_administrator'] == 0)
{
$roleMemHTML .= '<a class="admidio-icon-link" style="cursor:pointer;" href="javascript:profileJS.toggleDetailsOn('.$memberId.')"><i
$roleMemHTML .= '<a class="admidio-icon-link" style="cursor:pointer;" href="javascript:profileJS.toggleDetailsOn(\''.$memberUuid.'\')"><i
class="fas fa-edit" data-toggle="tooltip" title="'.$gL10n->get('PRO_CHANGE_DATE').'"></i></a>';
}
else
{
$roleMemHTML .= '<i class="fas fa-trash invisible"></i>';
$roleMemHTML .= '<a><i class="fas fa-edit invisible"></i></a>';
}

// You are not allowed to delete your own administrator membership, other roles could be deleted
if (($role->getValue('rol_administrator') == 1 && (int) $gCurrentUser->getValue('usr_id') !== (int) $user->getValue('usr_id'))
|| ($role->getValue('rol_administrator') == 0))
{
$roleMemHTML .= '<a class="admidio-icon-link openPopup" href="javascript:void(0);"
data-href="'.SecurityUtils::encodeUrl(ADMIDIO_URL.'/adm_program/system/popup_message.php', array('type' => $deleteMode, 'element_id' => 'role_'.(int) $role->getValue('rol_id'), 'database_id' => $memberId, 'name' => $role->getValue('rol_name'))).'"><i
data-href="'.SecurityUtils::encodeUrl(ADMIDIO_URL.'/adm_program/system/popup_message.php', array('type' => $deleteMode, 'element_id' => 'role_'.(int) $role->getValue('rol_id'), 'database_id' => $memberUuid, 'name' => $role->getValue('rol_name'))).'"><i
class="fas fa-trash-alt" data-toggle="tooltip" title="'.$gL10n->get('PRO_CANCEL_MEMBERSHIP').'"></i></a>';
}
else
{
$roleMemHTML .= '<i class="fas fa-trash invisible"></i>';
$roleMemHTML .= '<a><i class="fas fa-trash-alt invisible"></i></a>';
}
}

// only show info if system setting is activated
if((int) $gSettingsManager->get('system_show_create_edit') > 0)
{
$roleMemHTML .= '<a class="admidio-icon-link admMemberInfo" id="member_info_'.$memberId.'" href="javascript:void(0)"><i
$roleMemHTML .= '<a class="admidio-icon-link admMemberInfo" id="member_info_'.$memberUuid.'" href="javascript:void(0)"><i
class="fas fa-info-circle" data-toggle="tooltip" title="'.$gL10n->get('SYS_INFORMATIONS').'"></i></a>';
}
$roleMemHTML .= '</span>
</li>
<li class="list-group-item" id="membership_period_'.$memberId.'" style="visibility: hidden; display: none;">';
$form = new HtmlForm('membership_period_form_'.$memberId, SecurityUtils::encodeUrl(ADMIDIO_URL.FOLDER_MODULES.'/profile/profile_function.php', array('mode' => '7', 'user_uuid' => $user->getValue('usr_uuid'), 'mem_id' => $row['mem_id'])), null, array('type' => 'navbar', 'setFocus' => false, 'class' => 'admidio-form-membership-period'));
<li class="list-group-item" id="membership_period_'.$memberUuid.'" style="visibility: hidden; display: none;">';
$form = new HtmlForm('membership_period_form_'.$memberUuid, SecurityUtils::encodeUrl(ADMIDIO_URL.FOLDER_MODULES.'/profile/profile_function.php', array('mode' => '7', 'user_uuid' => $user->getValue('usr_uuid'), 'member_uuid' => $row['mem_uuid'])),
null, array('type' => 'navbar', 'method' => 'post', 'setFocus' => false, 'class' => 'admidio-form-membership-period'));
$form->addInput(
'membership_start_date_'.$memberId, $gL10n->get('SYS_START'), $member->getValue('mem_begin', $gSettingsManager->getString('system_date')),
'membership_start_date_'.$memberUuid, $gL10n->get('SYS_START'), $member->getValue('mem_begin', $gSettingsManager->getString('system_date')),
array('type' => 'date', 'maxLength' => 10)
);
$form->addInput(
'membership_end_date_'.$memberId, $gL10n->get('SYS_END'), $member->getValue('mem_end', $gSettingsManager->getString('system_date')),
'membership_end_date_'.$memberUuid, $gL10n->get('SYS_END'), $member->getValue('mem_end', $gSettingsManager->getString('system_date')),
array('type' => 'date', 'maxLength' => 10)
);
$form->addButton(
'btn_send_'.$memberId, $gL10n->get('SYS_OK'),
array('class' => 'btn btn-primary button-membership-period-form', 'data-admidio' => $memberId)
$form->addSubmitButton(
'btn_send_'.$memberUuid, $gL10n->get('SYS_OK'),
array('class' => 'btn btn-primary button-membership-period-form', 'data-admidio' => $memberUuid)
);
$roleMemHTML .= $form->show();
$roleMemHTML .= '</li>
<li class="list-group-item" id="member_info_'.$memberId.'_Content" style="display: none;">';
<li class="list-group-item" id="member_info_'.$memberUuid.'_Content" style="display: none;">';
// show information about user who creates the recordset and changed it
$roleMemHTML .= admFuncShowCreateChangeInfoById(
(int) $member->getValue('mem_usr_id_create'), $member->getValue('mem_timestamp_create'),
Expand Down

0 comments on commit 87f304f

Please sign in to comment.