Skip to content

Commit

Permalink
Clear orphaned session records. (#368)
Browse files Browse the repository at this point in the history
Co-authored-by: Niklas <ns@znuny.com>
Co-authored-by: Denny Korsukéwitz <dennykorsukewitz@gmail.com>
  • Loading branch information
3 people authored Jul 21, 2023
1 parent 640b06b commit 2bc51e7
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 1 deletion.
36 changes: 35 additions & 1 deletion Kernel/System/AuthSession.pm
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,13 @@ sub RemoveSessionByUser {
SessionID => $SessionID,
);

next SESSIONID if $SessionData{UserLogin} ne $Param{UserLogin};
if (
defined $SessionData{UserLogin}
&& ( $SessionData{UserLogin} ne $Param{UserLogin} )
)
{
next SESSIONID;
}

$Self->{Backend}->RemoveSessionID(
SessionID => $SessionID,
Expand Down Expand Up @@ -376,6 +382,34 @@ sub GetActiveSessions {
return $Self->{Backend}->GetActiveSessions(%Param);
}

=head2 GetOrphanedSessionIDs()
returns an array with orphaned session ids,
missing user-login defines an orphaned session for now
my @Sessions = $SessionObject->GetOrphanedSessionIDs();
=cut

sub GetOrphanedSessionIDs {
my ( $Self, %Param ) = @_;

my @OrphanedSessionIDs;
my @SessionIDs = $Self->GetAllSessionIDs();
for my $SessionID (@SessionIDs) {

my %SessionData = $Self->{Backend}->GetSessionIDData(
SessionID => $SessionID,
);

if ( !defined $SessionData{UserLogin} ) {
push @OrphanedSessionIDs, $SessionID;
}
}

return @OrphanedSessionIDs;
}

=head2 CleanUp()
clean-up of sessions in your system
Expand Down
56 changes: 56 additions & 0 deletions Kernel/System/Console/Command/Maint/Session/DeleteOrphaned.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# --
# Copyright (C) 2021 Znuny GmbH, https://znuny.org/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
# --

package Kernel::System::Console::Command::Maint::Session::DeleteOrphaned;

use strict;
use warnings;
use utf8;

use parent qw(Kernel::System::Console::BaseCommand);

our @ObjectDependencies = (
'Kernel::System::AuthSession',
);

sub Configure {
my ( $Self, %Param ) = @_;

$Self->Description('Delete orphaned sessions.');

return;
}

sub Run {
my ( $Self, %Param ) = @_;

my $SessionObject = $Kernel::OM->Get('Kernel::System::AuthSession');

$Self->Print("<yellow>Deleting orphaned sessions...</yellow>\n");

my @OrphanedSessions = $SessionObject->GetOrphanedSessionIDs();

for my $SessionID ( @OrphanedSessions ) {
my $Success = $SessionObject->RemoveSessionID(
SessionID => $SessionID,
);

if ( !$Success ) {
$Self->PrintError("Session $SessionID could not be deleted.");
return $Self->ExitCodeError();
}

$Self->Print(" $SessionID\n");
}

$Self->Print("<green>Done.</green>\n");

return $Self->ExitCodeOk();
}

1;
47 changes: 47 additions & 0 deletions Kernel/System/Console/Command/Maint/Session/ListOrphaned.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# --
# Copyright (C) 2021 Znuny GmbH, https://znuny.org/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
# --

package Kernel::System::Console::Command::Maint::Session::ListOrphaned;

use strict;
use warnings;
use utf8;

use parent qw(Kernel::System::Console::BaseCommand);

our @ObjectDependencies = (
'Kernel::System::AuthSession',
);

sub Configure {
my ( $Self, %Param ) = @_;

$Self->Description('List orphaned sessions.');

return;
}

sub Run {
my ( $Self, %Param ) = @_;

my $SessionObject = $Kernel::OM->Get('Kernel::System::AuthSession');

$Self->Print("<yellow>Listing orphaned sessions...</yellow>\n");

my @OrphanedSessions = $SessionObject->GetOrphanedSessionIDs();

for my $SessionID (@OrphanedSessions) {
$Self->Print(" $SessionID\n");
}

$Self->Print("<green>Done.</green>\n");

return $Self->ExitCodeOk();
}

1;
100 changes: 100 additions & 0 deletions scripts/test/RemoveOrphanedSessions.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# --
# Copyright (C) 2021 Znuny GmbH, https://znuny.org/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
# --

use strict;
use warnings;
use utf8;

use vars (qw($Self));

my $SessionObject = $Kernel::OM->Get('Kernel::System::AuthSession');
my $UserObject = $Kernel::OM->Get('Kernel::System::User');

$Kernel::OM->ObjectParamAdd(
'Kernel::System::UnitTest::Helper' => {
RestoreDatabase => 1,
},
);
my $HelperObject = $Kernel::OM->Get('Kernel::System::UnitTest::Helper');

# Create test users and a session for every one.
my @TestUserLogins;
for my $Count ( 1 .. 3 ) {
my ( $TestUserLogin, $TestUserID ) = $HelperObject->TestUserCreate();
push @TestUserLogins, $TestUserLogin;

my %UserData = $UserObject->GetUserData(
UserID => $TestUserID,
NoOutOfOffice => 1,
);

my $NewSessionID = $SessionObject->CreateSessionID(
%UserData,
UserLastRequest => $Kernel::OM->Create('Kernel::System::DateTime')->ToEpoch(),
UserType => 'User',
SessionSource => 'AgentInterface',
);
$Self->True(
$NewSessionID,
"SessionID '$NewSessionID' is created for user '$TestUserLogin'",
);
}

# orphan first session
my @SessionIDs = $SessionObject->GetAllSessionIDs();
my $OrphanedTestUserSessionID = $SessionIDs[0];

$SessionObject->UpdateSessionID(
SessionID => $OrphanedTestUserSessionID,
Key => 'UserLogin',
Value => undef,
);
$Self->True(
$OrphanedTestUserSessionID,
"SessionID '$OrphanedTestUserSessionID' has been orphaned",
);

# delete orphaned session via console command method
# ( i.e. bin/znuny.Console.pl Maint::Session::DeleteOrphaned for maintenance )
my $CommandObject = $Kernel::OM->Get('Kernel::System::Console::Command::Maint::Session::DeleteOrphaned');
my $ExitCode = $CommandObject->Execute();

$Self->Is(
$ExitCode,
$CommandObject->ExitCodeOk(),
"Orphaned session '$OrphanedTestUserSessionID' was deleted",
);

# Check for remaining sessions.
my @RemainingSessionIDs = $SessionObject->GetAllSessionIDs();

$Self->Is(
scalar @RemainingSessionIDs,
2,
"Ok, only one session was deleted, two remaining.",
);

# Check if orphaned session is removed.
for my $SessionID (@RemainingSessionIDs) {
if ( $SessionID eq $OrphanedTestUserSessionID ) {
$Self->False(
$OrphanedTestUserSessionID,
"Orphaned session: '$OrphanedTestUserSessionID' was not deleted",
);
}
else {
$Self->True(
$SessionID,
"Session '$SessionID' is found",
);
}
}

# Restore to the previous state is done by RestoreDatabase.

1;

0 comments on commit 2bc51e7

Please sign in to comment.