Replace fields that use a group that is deleted with a safe group, like Admin. rfe#76

This commit is contained in:
Colin Kuskie 2009-06-12 20:43:03 +00:00
parent b788f82b0b
commit fb33138e33
3 changed files with 300 additions and 6 deletions

View file

@ -1,6 +1,7 @@
7.7.11
- Fixed a bug where empty version tags were not deleted. (Martin Kamerbeek / Oqapi)
- fixed: deploying a package doesn't commit version tag with autocommit on
- fixed rfe #76: group delete causes problems
7.7.10
- Made a change to LDAP auth that adds an OR to that query so that it also searches for a row with fieldData REGEXP '^uid=(value-from-ldap-directory-server),'. (Wes Morgan)

View file

@ -19,6 +19,8 @@ use Tie::CPHash;
use WebGUI::LDAPLink;
use WebGUI::Macro;
use WebGUI::Utility;
use WebGUI::Pluggable;
use WebGUI::International;
=head1 NAME
@ -261,12 +263,13 @@ Deletes this group from the group related tables in the database and calls clear
=cut
sub delete {
my $self = shift;
$self->clearCaches;
$self->session->db->write("delete from groups where groupId=?", [$self->getId]);
$self->session->db->write("delete from groupings where groupId=?", [$self->getId]);
$self->session->db->write("delete from groupGroupings where inGroup=? or groupId=?", [$self->getId, $self->getId]);
undef $self;
my $self = shift;
$self->resetGroupFields;
$self->clearCaches;
$self->session->db->write("delete from groups where groupId=?", [$self->getId]);
$self->session->db->write("delete from groupings where groupId=?", [$self->getId]);
$self->session->db->write("delete from groupGroupings where inGroup=? or groupId=?", [$self->getId, $self->getId]);
undef $self;
}
#-------------------------------------------------------------------
@ -1139,6 +1142,117 @@ sub new {
}
#-------------------------------------------------------------------
=head2 resetGroupFields ( )
Looks through WebGUI and resets any group field that it can find, that uses this group,
to the admin group, 3. Called internally by delete.
Currently handes these areas:
=over 4
=item *
Anything in an Asset definition that is labeled as type group. JSON data is not handled.
=item *
Everything in Operation/Settings, from its definition subroutine.
=item *
Settings fields hand picked from Shop/Admin and Account/FriendManager.
=item *
Any Workflow Activity data from the definition that is labeled as type group.
=back
=cut
sub resetGroupFields {
my $self = shift;
my $gid = $self->getId;
my $session = $self->session;
my $db = $session->db;
my $config = $session->config;
my $assets = $config->get('assets');
my $tableCache = {};
##Note, I did assets in SQL instead of using the API because you would have to
##instanciate every version of the asset that used the group. This should be much quicker
ASSET: foreach my $asset (keys %{ $assets }) {
my $definition = WebGUI::Pluggable::instanciate($asset, 'definition', [$session]);
SUBDEF: foreach my $subdef (@{ $definition }) {
next SUBDEF if exists $tableCache->{$subdef->{tableName}};
PROP: while (my ($fieldName, $properties) = each %{ $subdef->{properties} }) {
next PROP unless $properties->{fieldType} eq 'group';
push @{ $tableCache->{$subdef->{tableName}} }, $fieldName;
}
}
}
##VersionTags
$tableCache->{assetVersionTag} = ['groupToUse'];
$tableCache->{adSpace} = ['groupToPurchase'];
foreach my $tableName (keys %{ $tableCache }) {
foreach my $fieldName (@{ $tableCache->{$tableName} }) {
my $sql = sprintf 'UPDATE %s SET %s=3 where %s=?',
$db->dbh->quote_identifier($tableName),
(($db->dbh->quote_identifier($fieldName)) x 2);
$db->write($sql, [ $gid ]);
}
}
SETTINGS: {
my $setting = $session->setting;
my $i18n = WebGUI::International->new($session);
my $definition = WebGUI::Pluggable::run('WebGUI::Operation::Settings', 'definition', [$session, $i18n]);
FIELD: foreach my $field (@{ $definition }) {
next FIELD unless $field->{fieldType} eq 'group'
and $setting->get($field->{name}) eq $gid;
$setting->set($field->{name}, 3);
}
}
##Settings in the settings table not from Operation/Settings. These should all
##be moved to definition style subroutines for future auto-probing.
AUX_SETTINGS: {
##These are extra fields
my $setting = $session->setting;
my @extraFields = qw/groupIdCashier groupIdAdminCommerce/; ##Shop/Admin
push @extraFields, qw/groupIdAdminFriends groupsToManageFriends/; ##Account/FriendManager
FIELD: foreach my $field (@extraFields) {
next FIELD unless $setting->get($field) eq $gid;
$setting->set($field, 3);
}
}
ACTIVITY: {
my $workflowActivities = $config->get('workflowActivities');
my @activities;
foreach my $wfActivities (values %{ $workflowActivities} ) {
push @activities, @{ $wfActivities };
}
use Data::Dumper;
warn Dumper \@activities;
foreach my $activity (@activities) {
my $definition = WebGUI::Pluggable::instanciate($activity, 'definition', [$session]);
my $sth = $db->prepare('UPDATE WorkflowActivityData set value=3 where name=? and value=?');
SUBDEF: foreach my $subdef (@{ $definition }) {
PROP: while (my ($fieldName, $properties) = each %{ $subdef->{properties} }) {
next PROP unless $properties->{fieldType} eq 'group';
warn $fieldName;
warn $gid;
$sth->execute([$fieldName, $gid]);
}
}
}
}
##Inbox messages, inbox table
return 1;
}
#-------------------------------------------------------------------
=head2 scratchFilter ( [ value ] )

179
t/Group/resetGroupFields.t Normal file
View file

@ -0,0 +1,179 @@
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
#-------------------------------------------------------------------
# Please read the legal notices (docs/legal.txt) and the license
# (docs/license.txt) that came with this distribution before using
# this software.
#-------------------------------------------------------------------
# http://www.plainblack.com info@plainblack.com
#-------------------------------------------------------------------
use FindBin;
use strict;
use lib "$FindBin::Bin/../lib";
use WebGUI::Test;
use WebGUI::Session;
use WebGUI::Asset;
use WebGUI::Group;
use Test::More;
use Test::Deep;
plan tests => 10;
my $session = WebGUI::Test->session;
my $assetGroup = WebGUI::Group->new($session, 'new');
WebGUI::Test->groupsToDelete($assetGroup);
my $settingGroup = WebGUI::Group->new($session, 'new');
WebGUI::Test->groupsToDelete($settingGroup);
my $activityGroup = WebGUI::Group->new($session, 'new');
WebGUI::Test->groupsToDelete($activityGroup);
my $home = WebGUI::Asset->getDefault($session);
my $snippet1 = $home->addChild({
className => 'WebGUI::Asset::Snippet',
groupIdEdit => $assetGroup->getId,
groupIdView => 7,
snippet => 'one',
});
my $snippet2 = $home->addChild({
className => 'WebGUI::Asset::Snippet',
groupIdEdit => 7,
groupIdView => 7,
snippet => 'two',
});
my $snippet3 = $home->addChild({
className => 'WebGUI::Asset::Snippet',
groupIdEdit => $assetGroup->getId,
groupIdView => $assetGroup->getId,
snippet => 'three',
});
my $gallery1 = $home->addChild({
className => 'WebGUI::Asset::Wobject::Gallery',
groupIdView => 7,
groupIdEdit => $assetGroup->getId,
groupIdAddComment => $assetGroup->getId,
});
cmp_deeply(
$gallery1->get,
superhashof({
groupIdEdit => $assetGroup->getId,
groupIdView => 7,
groupIdAddComment => $assetGroup->getId,
}),
'gallery set up correctly'
);
cmp_deeply(
$snippet1->get,
superhashof({
groupIdEdit => $assetGroup->getId,
groupIdView => 7,
}),
'groupIdEdit updated on test snippet'
);
my $workflow = WebGUI::Workflow->create($session,
{
enabled => 1,
objectType => 'User',
mode => 'realtime',
},
);
WebGUI::Test->originalConfig('workflowActivities');
$session->config->addToArray('workflowActivities/User', 'WebGUI::Workflow::Activity::AddUserToGroup');
my $userActivity = $workflow->addActivity('WebGUI::Workflow::Activity::AddUserToGroup');
$userActivity->set('className', 'WebGUI::Workflow::Activity::AddUserToGroup');
$userActivity->set('groupId', $activityGroup->getId);
is($userActivity->get('groupId'), $activityGroup->getId, 'group in Workflow Activity set to test group');
###################################################################
#
# Asset tests
#
###################################################################
$assetGroup->delete;
my $newSnippet1 = WebGUI::Asset->newByDynamicClass($session, $snippet1->getId);
cmp_deeply(
$newSnippet1->get,
superhashof({
groupIdEdit => 3,
groupIdView => 7,
}),
'groupIdEdit updated on test snippet'
);
my $newSnippet2 = WebGUI::Asset->newByDynamicClass($session, $snippet2->getId);
cmp_deeply(
$newSnippet2->get,
superhashof({
groupIdEdit => 7,
groupIdView => 7,
}),
'other snippet not touched'
);
my $newSnippet3 = WebGUI::Asset->newByDynamicClass($session, $snippet3->getId);
cmp_deeply(
$newSnippet3->get,
superhashof({
groupIdEdit => 3,
groupIdView => 3,
}),
'multiple fields updated'
);
my $newGallery1 = WebGUI::Asset->newByDynamicClass($session, $gallery1->getId);
cmp_deeply(
$newGallery1->get,
superhashof({
groupIdEdit => 3,
groupIdView => 7,
groupIdAddComment => 3,
}),
'multiple fields and tables updated'
);
###################################################################
#
# Setting tests
#
###################################################################
$session->setting->set('groupIdAdminUser', $settingGroup->getId);
is($session->setting->get('groupIdAdminUser'), $settingGroup->getId, 'group in Setting set up');
$settingGroup->delete;
is($session->setting->get('groupIdAdminUser'), 3, 'group in Setting reset to Admin');
###################################################################
#
# Workflow Activity tests
#
###################################################################
$activityGroup->delete;
my $userActivity2 = WebGUI::Workflow::Activity->new($session, $userActivity->getId);
is ($userActivity2->get('groupId'), 3, 'group in Workflow Activity set to Admin');
WebGUI::Test->tagsToRollback(WebGUI::VersionTag->getWorking($session));