Apache2-Controller

 view release on metacpan or  search on metacpan

lib/Apache2/Controller/Directives.pm  view on Meta::CPAN

package Apache2::Controller::Directives;

=head1 NAME

Apache2::Controller::Directives - server config directives for A2C

=head1 VERSION

Version 1.001.001

=cut

use version;
our $VERSION = version->new('1.001.001');

=head1 SYNOPSIS

 # apache2 config file
 PerlLoadModule Apache2::Controller::Directives

 # for Apache2::Controller::Render::Template settings:
 A2C_Render_Template_Path /var/myapp/templates

 # etc.

All values are detainted using C<< m{ \A (.*) \z }mxs >>,
since they are assumed to be trusted because they come
from the server config file.  As long as you don't give
your users the ability to set directives, it should be okay.

=cut

use strict;
use warnings FATAL => 'all';
use English '-no_match_vars';

use Carp qw( croak );
use Log::Log4perl qw(:easy);
use YAML::Syck;
use Readonly;

use Apache2::Module ();
use Apache2::Const -compile => qw( OR_ALL NO_ARGS TAKE1 ITERATE ITERATE2 RAW_ARGS );
use Apache2::Controller::X;

use Apache2::Controller::Const qw( @RANDCHARS );

my @directives = (

    # dispatch
    {
        name            => 'A2C_Dispatch_Map',
        func            => __PACKAGE__.'::A2C_Dispatch_Map',
        req_override    => Apache2::Const::OR_ALL,
        args_how        => Apache2::Const::ITERATE,
        errmsg          => 'A2C_Dispatch_Map /path/to/yaml/syck/dispatch/map/file',
    },

    # template rendering
    { 
        name            => 'A2C_Render_Template_Path',
        func            => __PACKAGE__.'::A2C_Render_Template_Path',
        req_override    => Apache2::Const::OR_ALL,
        args_how        => Apache2::Const::ITERATE,
        errmsg          => 'A2C_Render_Template_Path /primary/path [/second ... [/n]]',
    },
    {
        name            => 'A2C_Render_Template_Opts',
        func            => __PACKAGE__.'::A2C_Render_Template_Opts',
        req_override    => Apache2::Const::OR_ALL,
        args_how        => Apache2::Const::ITERATE2,
        errmsg          => q{
            # specify Template Toolkit options:
            A2C_Render_Template_Opts INTERPOLATE 1
            A2C_Render_Template_Opts PRE_PROCESS header scripts style
            A2C_Render_Template_Opts POST_CHOMP  1
        },
    },

    # session stuff
    {
        name            => 'A2C_Session_Class',
        func            => __PACKAGE__.'::A2C_Session_Class',
        req_override    => Apache2::Const::OR_ALL,
        args_how        => Apache2::Const::TAKE1,
        errmsg          => 'example: A2C_Session_Class Apache::Session::File'

lib/Apache2/Controller/Directives.pm  view on Meta::CPAN

        errmsg          => 'example: A2C_Auth_OpenID_Allow_Login',
    },
    {
        name            => 'A2C_Auth_OpenID_Consumer_Secret',
        req_override    => Apache2::Const::OR_ALL,
        args_how        => Apache2::Const::RAW_ARGS,
        errmsg          => q{
            # specify a constant secret for continuity across server restarts
            A2C_Auth_OpenID_Consumer_Secret  foobar

            # if no parameters, server startup will generate a secret,
            # but this won't work for cluster farms etc.
            A2C_Auth_OpenID_Consumer_Secret
        },
    },
    {
        name            => 'A2C_Auth_OpenID_NoPreserveParams',
        req_override    => Apache2::Const::OR_ALL,
        args_how        => Apache2::Const::NO_ARGS,
        errmsg          => 'example: A2C_Auth_OpenID_NoPreserveParams',
    },
);

Apache2::Module::add(__PACKAGE__, \@directives);

=head1 Apache2::Controller::Dispatch

See L<Apache2::Controller::Dispatch>

=head2 A2C_Dispatch_Map

This is the path to a file compatible with L<YAML::Syck>.
If you do not provide a C<< dispatch_map() >> subroutine,
the hash will be loaded with this file.

Different subclasses of L<Apache2::Controller::Dispatch>
have different data structures.  YMMV.

Or, if you just specify a package name, it will generate
a dispatch map with one 'default' entry with that package.

=cut

sub A2C_Dispatch_Map {
    my ($self, $parms, $value) = @_;

    ($value) = $value =~ m{ \A (.*) \z }mxs;

    if ($value =~ m{ :: }mxs) {
        $self->{A2C_Dispatch_Map} = { default => $value };
        return;
    }

    my $file = $value;
  # DEBUG("using file '$file' as A2C_Dispatch_Map");
    croak "A2C_Dispatch_Map $file does not exist or is not readable."
        if !(-e $file && -f _ && -r _);
    
    # why not go ahead and load the file!

    # slurp it in so it can be detainted.

    my $file_contents;
    {   local $/;
        open my $loadfile_fh, '<', $file 
            || croak "Cannot read A2C_Dispatch_Map $file: $OS_ERROR";
        $file_contents = <$loadfile_fh>;
        close $loadfile_fh;
    }

    eval { $self->{A2C_Dispatch_Map} = Load($file_contents) };
    croak "Could not load A2C_Dispatch_Map $file: $EVAL_ERROR" if $EVAL_ERROR;

  # DEBUG("success!");
    return;
}

=head1 Apache2::Controller::Render::Template

See L<Apache2::Controller::Render::Template>.

=head2 A2C_Render_Template_Path

This is the base path for templates used by 
Apache2::Controller::Render::Template.  The directive takes only
one parameter and verifies that the directory exists and is readable.

(At startup time Apache2 is root... this should verify readability by 
www user?  Hrmm how is it going to figure out what user that is?
It will have to access the server config via $parms. Except that
this does not appear to work?  It returns an empty hash.)

=cut

sub A2C_Render_Template_Path {
    my ($self, $parms, @directories_untainted) = @_;

    my @directories = map { 
        my ($val) = $_ =~ m{ \A (.*) \z }mxs;
        $val;
    } @directories_untainted;

    # uhh... this doesn't work?
  # my $srv_cfg = Apache2::Module::get_config($self, $parms->server);
  # DEBUG(sub{"SERVER CONFIG:\n".Dump({
  #     map {("$_" => $srv_cfg->{$_})} keys %{$srv_cfg}
  # }) });
  # DEBUG("server is ".$parms->server);

    # I need to figure out how to merge these or something

    croak("A2C_Render_Template_Path '$_' does not exist or is not readable.") 
        for grep !( -d $_ && -r _ ), @directories;

    my $current = $self->{A2C_Render_Template_Path} ||= [ ];
    DEBUG sub { "pushing (@directories) to (@{$current})" };

    push @{ $self->{A2C_Render_Template_Path} }, @directories;
}

=head2 A2C_Render_Template_Opts

 <location "/where/template/is/used">
     A2C_Render_Template_Opts INTERPOLATE 1
     A2C_Render_Template_Opts PRE_PROCESS header meta style scripts
     A2C_Render_Template_Opts POST_CHOMP  1
 </location>

Options for Template Toolkit.  See L<Template>.

You can also implement C<<get_template_opts>> in your controller subclass,
which simply returns the hash reference of template options.
See L<Apache2::Controller::Render::Template>.

Note the behavior is to merge values specified at multiple levels
into array references.  i.e. a subdirectory could specify an
additional C<<PRE_PROCESS>> template or whatever.  YMMV.
It should be this way, at any rate!

=cut

sub A2C_Render_Template_Opts {
    my ($self, $parms, $key, $val) = @_;
    $self->hash_assign('A2C_Render_Template_Opts', $key, $val);
    return;
}

=head1 Apache2::Controller::Session

See L<Apache2::Controller::Session>.

=head2 A2C_Session_Class

 A2C_Session_Class Apache::Session::File

Single argument, the class for the tied session hash.  L<Apache::Session>.

=cut

sub A2C_Session_Class {
    my ($self, $parms, $class) = @_;



( run in 1.013 second using v1.01-cache-2.11-cpan-39bf76dae61 )