Apache-AxKit-Plugin-Session

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

Revision history for Perl extension Session.pm.

1.00
	- bug fixes as usual
	- a new globals storage mechanism
	- non-exclusive logins
	- some more AxKit::XSP::Auth tags
	- allow cookies to be deleted when browser is closed

0.98
	- first release after various internal versions
	- numerous bugfixes
	- better docs
	- less dependencies
	- better interoperability

clean-sessions.pl  view on Meta::CPAN

use strict;
use warnings;
use Apache::Session::File;

# Would be nice to make it read these
# config options from httpd.conf

my $sessiondir  = '/www/sessions';                         # session directory
my $locksdir    = '/www/sessions/locks';                   # locks directory
my $expire      = '30';                                    # timeout period
my $globals     = 'Tie::SymlinkTree,/tmp/globals';         # global file name

# safety measure
die "Run this script in your session dir!" if ! -f $globals;

# Get global data
my @tie = split(/,/,$globals);
eval "require $tie[0];";
tie my %global, @tie;

chdir($sessiondir);
foreach (glob("*")) {
    next unless -f $_;
    
    my $sessionfile = $_;
    
    # Get session data
    tie my %session, 'Apache::Session::File', $sessionfile, {
        Directory       => $sessiondir,
        LockDirectory   => $locksdir,
    };

    # remove expired session files and update globals
    if (int(time()/300) > $session{'auth_last_access'}+$expire) {
        
        delete($global{'auth_online_users'}{$session{'auth_access_user'}});
        unlink($sessionfile);
        unlink($locksdir.'/Apache-Session-'.$sessionfile.'.lock');
    }
}

lib/Apache/AxKit/Plugin/Session.pm  view on Meta::CPAN

    } elsif (!exists $$session{'auth_remote_ip'}) {
        $$session{'auth_remote_ip'} = $remote;
    }

    # force new session ID every 5 minutes if Apache::Session::Counted is used, don't write session file on each access
    $$session{'auth_last_access'} = int(time()/300) if $$session{'auth_last_access'} < int(time()/300);

    # store session hash in pnotes
    $r->pnotes('SESSION',$session);

    # global application data
    my $globals = $mr->pnotes('GLOBAL');
    if (!$globals) {
        $globals = {};
	if (my $tie = $r->dir_config($auth_name.'Global')) {
		my ($tie, @tie) = split(/,/,$tie);
		eval "require $tie" || die "Could not load ${auth_name}Global module $tie[0], did you install it? $@";
		tie(%$globals, $tie, @tie) || die "Could tie ${auth_name}Global: $@";
		$r->register_cleanup(sub { _cleanup_session($self, $globals) });
	}
    }
    $r->pnotes('GLOBAL',$globals);

    return $session;
}

# this is a NO-OP! Don't use this one (or ->login) directly,
# unless you have verified the credentials yourself or don't
# want user logins
sub authen_cred($$\@) {
    my ($self, $r, @credentials) = @_;
    $self->debug(3,"--------- authen_cred(".join(',',@_).")");

lib/Apache/AxKit/Plugin/Session.pm  view on Meta::CPAN

    PerlSetVar AxKitSessionExpire 30

Which session module should be used?

    PerlSetVar AxKitSessionManager Apache::Session::File

Where should session files (data and locks) go?

    PerlSetVar AxKitSessionDir /tmp/sessions

Do you want global data? ($r->pnotes('GLOBALS') and AxKit::XSP::Globals)

    PerlSetVar AxKitSessionGlobal Tie::SymlinkTree,/tmp/globals

How's the "guest" user called?

    PerlSetVar AxKitSessionGuest guest

Want to check the IP address for sessions?

    PerlSetVar AxKitSessionIPCheck 1

Beware that IP checking is dangerous: Some people have different IP addresses

lib/Apache/AxKit/Plugin/Session.pm  view on Meta::CPAN

It combines authentication and authorization in Apache::AuthCookieURL style with session management
via one of the Apache::Session modules. It should even work with Apache::Session::Counted. See those
manpages for more information, but be sure to note the differences in configuration!

In addition to Apache::AuthCookieURL, you get:

=over 4

=item * session data in $r->pnotes('SESSION')

=item * global application data in $r->pnotes('GLOBAL')

=item * sessions without the need to login (guest account)

=item * automatic expiration of sessions after 30 minutes (with
    automatic degradation to guest account, if any)

=item * remote ip check of sessions, for a tiny bit more security

=item * authorization based on users, groups or levels, including logical
        AND, OR and NOT of any requirement

lib/Apache/AxKit/Plugin/Session.pm  view on Meta::CPAN


Note that the session dir will always leak. You will have to do manual cleanup, since
automatic removal of old session records is only possible in some cases. The
distribution tarball contains an example script to do that.

=head1 CONFIGURATION SETTINGS

See the synopsis for an overview and quick explanation.

All settings are set with PerlSetVar and may occur in any location PerlSetVar is allowed in,
except SessionPrefix, which must be a global setting.

=over 4

=item * SessionPrefix, AxKitSessionCache, AxKitSessionLoginScript, AxKitSessionLogoutURI,
AxKitSessionNoCookie, AxKitSession(Path|Expires|Domain|Secure)

These settings are similar to Apache::AuthCookieURL. Some of them are very advanced
and probably not needed at all. Some may be broken by now. Please only use the documented
variables shown in the synopsis.

lib/Apache/AxKit/Plugin/Session.pm  view on Meta::CPAN

value (the default) disables automatic guest login. If logins are used at
all, this is the only way to get session management for unknown users. If
no logins are used, this MUST be set to some value.

Example: PerlSetVar AxKitSessionGuest guest

=item * AxKitSessionGlobal

Often you want to share a few values across all sessions. That's what
$r->pnotes('GLOBALS') is for: It works just like the session hash, but it is
shared among all sessions. In previous versions, globals were always available,
but since many users didn't care and there were grave problems in the old
implementation, behaviour has changed: You get a fake GLOBALS hash unless you
specify the sotrage method to use using this setting. It takes a comma-separated
list of "tie" parameters, starting with the name of the module to use. Do not use
spaces, and you should use a module that works with a minimum of locking, like
L<Tie::SymlinkTree>. Otherwise, you could get server lockups or bad performance
(which is what you often got in previous versions as well).

Example: PerlSetVar AxKitSessionGlobal Tie::SymlinkTree,/tmp/globals

=item * AxKitSessionIPCheck

The level of IP matching in sessions. A session id is only valid when the
connection is coming from the same remote address. This setting lets you
adjust what will be checked: 0 = nothing, 1 = numeric IP address or
HTTP X-Forwarded-For header, if present, 2 = numeric IP address with last
part stripped off, 3 = whole numeric IP address.

Example: PerlSetVar AxKitSessionIPCheck 3

lib/AxKit/XSP/Auth.pm  view on Meta::CPAN

if (defined $attr_destination) {
	$rc = $auth_type->login($r,$attr_destination);
} else {
	$rc = $auth_type->login($r);
}
$session = $r->pnotes('SESSION');
EOC
        $res .= set_access(@_);
        return $res.<<'EOC';
$rc = $auth_type->external_redirect($attr_destination||$r->uri) if $rc == OK && $attr_destination ne 'none';
my $old_id = $$global{'auth_online_users'}{$$session{'auth_access_user'}};
if ($attr_exclusive ne '0' && lc($attr_exclusive) ne 'no' && lc($attr_exclusive) ne 'off') {
	if ($old_id && $old_id ne $$session{'_session_id'}) {
		my $oldsession = $auth_type->_get_session_from_store($r,$old_id);
		eval {
			%$oldsession = ('_session_id' => $old_id);
			tied(%$oldsession)->delete;
		};
	}
	$$global{'auth_online_users'} ||= {};
	$$global{'auth_online_users'}{$$session{'auth_access_user'}} = $$session{'_session_id'};
	$$global{'auth_logins'}++;
}
throw Apache::AxKit::Exception::Retval(return_code => $rc) unless $attr_destination eq 'none';
EOC
}

sub logout : XSP_attribOrChild(destination)
{
	return set_access(@_).<< 'EOC';
my $auth_type = $r->auth_type || 'Apache::AxKit::Plugin::Session';
no strict 'refs';
my $rc;
if (exists $$global{'auth_online_users'}{$$session{'auth_access_user'}}) {
	delete $$global{'auth_online_users'}{$$session{'auth_access_user'}};
	$$global{'auth_logouts'}++;
}
if (defined $attr_destination) {
	$rc = $auth_type->logout($r,$attr_destination);
} else {
	$rc = $auth_type->logout($r,$r->uri);
}
throw Apache::AxKit::Exception::Retval(return_code => $rc);
EOC
}

lib/AxKit/XSP/Auth.pm  view on Meta::CPAN

=head3 C<<login>>

This tag logs in a user name. It works just like set-access, but additionally the
user name is checked and any existing session of that user is invalidated, so that
users can be logged in only once. Moreover, an external redirect is triggered.
You can provide a 'destination' attribute or child tag to set the destination location,
otherwise, the HTTP request parameter 'destination' is used. If you set 'destination'
to "none", no redirect is performed.

You can add the parameter C<<exclusive="no">> to allow a user to be logged in multiple
times. Note that you need globals enabled to have the exclusive-login mechanism to work.


=head3 C<<logout>>

This tag invalidates the current session, thus logging the user out. If you supply a
'destination' tag or attribute, or if the server config specifies one, a redirect
is triggered.

=head2 Object permission tags

lib/AxKit/XSP/Global.pm  view on Meta::CPAN

# Axkit::XSP::Global - application global variable management
package AxKit::XSP::Global;
use strict;
use Apache::AxKit::Language::XSP::SimpleTaglib;
use Apache::AxKit::Plugin::Session;
our $VERSION = 0.98;
our $NS = 'http://www.creITve.de/2002/XSP/Global';

sub start_document {
        return 'use Apache::AxKit::Plugin::Session;'."\n".
               'use Time::Piece;'."\n";
}

sub start_xml_generator {
        return 'my $global = Apache->request->pnotes("GLOBAL");'."\n\n";
}

package AxKit::XSP::Global::Handlers;

sub get_attribute : XSP_attribOrChild(name) XSP_exprOrNode(attribute) XSP_nodeAttr(name,$attr_name)
{
        return '$attr_name =~ s/^(_|auth_|X)/X\1/; $$global{$attr_name};';
}
*get_value = \&get_attribute;

sub get_attribute_names : XSP_exprOrNodelist(name)
{
        return 'map { m/^(?:_|auth_)/?():substr($_,0,1) eq "X"?substr($_,1):$_ } keys %$global';
}
*get_value_names = \&get_attribute_names;

sub get_creation_time : XSP_attrib(as) XSP_exprOrNode(creation-time)
{
        my ($e, $tag, %attribs) = @_;
        if ($attribs{'as'} eq 'string') {
                return 'localtime($$global{"_creation_time"})->strftime("%a %b %d %H:%M:%S %Z %Y");';
        } else {
                return '$$global{"_creation_time"};';
        }
}

sub remove_attribute : XSP_attribOrChild(name)
{
        return '$attr_name =~ s/^(_|auth_|X)/X\1/; delete $$global{$attr_name};';
}
*remove_value = \&remove_attribute;

sub set_attribute : XSP_attribOrChild(name) XSP_captureContent
{
        return '$attr_name =~ s/^(_|auth_|X)/X\1/; $$global{$attr_name} = $_;';
}
*put_value = \&set_attribute;

1;

__END__

=head1 NAME

AxKit::XSP::Global - Application global variables tag library for AxKit eXtensible Server Pages.

=head1 SYNOPSIS

Add the global: namespace to your XSP C<<xsp:page>> tag:

    <xsp:page
         language="Perl"
         xmlns:xsp="http://apache.org/xsp/core/v1"
         xmlns:global="http://www.creITve.de/2002/XSP/Session"
    >

Add this taglib to AxKit (via httpd.conf or .htaccess):

    AxAddXSPTaglib AxKit::XSP::Global

=head1 DESCRIPTION

The XSP globals taglib provides basic application global variable
operations to XSP similar to the Cocoon2 Session taglib specification.
The global variables provided by this taglib have limited persistance. They may
get removed on server restarts or storage cleanups. Don't use them for
persistent data which belongs into some kind of tatabase. Example uses:
tracking of logged in users (The Auth taglib does that), accumulating daily
statistics, changing global application state for limited time.

This taglib works in conjunction with Apache::AxKit::Plugin::Session,
which does all the hard work. There are several configuration variants
available, see the man page for details.

=head1 Tag Reference

All tags returning a value look at the attribute 'as' to determine the type
of result. If it equals 'node', the result gets placed inside an XML node
with a name like the original tag minus 'get-'.

lib/AxKit/XSP/Global.pm  view on Meta::CPAN


Tags that return a list create multiple XML nodes (for 'as="node"') or a concatenation
of the values without any separator.

Tags that use their contents as input should only get text nodes (including
<xsp:expr>-style tags). Attribute nodes as mentioned in the description may be used,
of course.

All tags ignore leading and trailing white space.

=head2 C<<global:get-attribute>>

This tag retrieves an attribute value.  It accepts either an attribute or
child node called 'name'.  The value passed as 'name' determines the key
to retrieve data from the global storage.

=head2 C<<global:set-attribute>>

This tag sets an attribute value.  It accepts either an attribute or
child node called 'name'.  The value passed in 'name' determines the key
to store the contents of this tag into the global storage.

=head2 C<<global:get-creation-time>>

Returns the time the current storage got created. This can happen after server
restarts or after 'hot' storage cleanups. For this tag, the "as" attribute has
two more values: 'long' (default) returns the time as seconds since 1970-01-01,
00:00 UTC; 'string' returns a textual representation of the date and time.

=head2 C<<global:remove-attribute>>

Removes an attribute from the global storage.  It accepts either an attribute or
child node called 'name' which indicates which attribute to remove.

=head1 BUGS

This software has beta quality. Use with care and contact the author if any problems occur.

=head1 AUTHOR

Jörg Walter <jwalt@cpan.org>



( run in 0.220 second using v1.01-cache-2.11-cpan-1d5ca39e368 )