Concierge-Sessions
view release on metacpan or search on metacpan
lib/Concierge/Sessions/File.pm view on Meta::CPAN
package Concierge::Sessions::File v0.11.1;
use v5.36;
use parent 'Concierge::Sessions::Base';
use File::Spec;
use Carp qw(croak);
use JSON::PP;
sub new {
my ($class, %args) = @_;
my $self = $class->SUPER::new(%args);
$self->{storage_dir} = $args{storage_dir} || '/tmp/sessions';
unless (-d $self->{storage_dir}) {
unless (mkdir $self->{storage_dir}) {
croak "Failed to create storage directory '$self->{storage_dir}': $!";
}
}
unless (chmod 0700, $self->{storage_dir}) {
croak "Failed to set permissions on storage directory '$self->{storage_dir}': $!";
}
return $self;
}
sub create_session {
my ($self, %args) = @_;
return { success => 0, message => "Cannot create session without user_id" }
unless $args{user_id};
my $user_id = $args{user_id};
# Delete any existing sessions for this user (enforce single session per user)
$self->delete_user_session($user_id);
my $session_id = $self->generate_session_id();
my $session_file = File::Spec->catfile($self->{storage_dir}, $session_id);
# Write over session file if it already exists (unlikely)
my $fh;
unless (open $fh, '>', $session_file) {
return { success => 0, message => "Cannot create session file: $!" };
}
unless (chmod 0600, $session_file) {
close $fh;
return { success => 0, message => "Cannot set session file permissions: $!" };
}
# Build session_info structure
my $now = time();
# Handle session timeout: 'indefinite' or numeric value in seconds
my $timeout = $args{session_timeout} || $self->{session_timeout};
my $expiration;
if (defined $timeout && $timeout eq 'indefinite') {
$expiration = 'indefinite';
} else {
$expiration = $now + $timeout;
}
my $data = $args{data} || {}; # for app data
my $session_info = {
session_id => $session_id,
user_id => $user_id,
created_at => $now,
expires_at => $expiration,
last_updated => $now,
session_timeout => $timeout,
status => {
state => 'active',
dirty => 0,
},
data => $data,
};
# Encode to JSON with pretty formatting and write with trailing newline
my $json = JSON::PP->new->utf8->pretty->encode($session_info);
unless (print $fh $json, "\n") {
close $fh;
return { success => 0, message => "Cannot write to session file: $!" };
}
unless (close $fh) {
return { success => 0, message => "Cannot close session file: $!" };
}
return { success => 1, session_id => $session_id };
}
sub get_session_info {
my ($self, $session_id) = @_;
unless ($session_id) {
return { success => 0, message => "Session ID required to retrieve session from File backend" };
}
my $session_file = File::Spec->catfile($self->{storage_dir}, $session_id);
unless (-f $session_file) {
return { success => 0, message => "Session file not found" };
}
my $fh;
unless (open $fh, '<', $session_file) {
( run in 0.531 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )