From 755812601c33679bd32deaac58e6fe229ef7f9fa Mon Sep 17 00:00:00 2001 From: Chia-liang Kao Date: Wed, 6 Aug 2008 22:53:18 +0000 Subject: [PATCH] RT::Authen::OpenID2 --- MANIFEST | 15 ++ META.yml | 13 ++ Makefile.PL | 15 ++ html/Callbacks/OpenID/Elements/Login/Default | 13 ++ html/Callbacks/OpenID/autohandler/Auth | 95 ++++++++++ inc/Module/Install.pm | 171 +++++++++++++++++ inc/Module/Install/Base.pm | 57 ++++++ inc/Module/Install/Can.pm | 41 ++++ inc/Module/Install/Fetch.pm | 89 +++++++++ inc/Module/Install/Makefile.pm | 146 ++++++++++++++ inc/Module/Install/Metadata.pm | 190 +++++++++++++++++++ inc/Module/Install/RTx.pm | 158 +++++++++++++++ inc/Module/Install/Win32.pm | 66 +++++++ inc/Module/Install/WriteAll.pm | 39 ++++ lib/RT/Authen/OpenID.pm | 15 ++ 15 files changed, 1123 insertions(+) create mode 100644 MANIFEST create mode 100644 META.yml create mode 100644 Makefile.PL create mode 100644 html/Callbacks/OpenID/Elements/Login/Default create mode 100644 html/Callbacks/OpenID/autohandler/Auth create mode 100644 inc/Module/Install.pm create mode 100644 inc/Module/Install/Base.pm create mode 100644 inc/Module/Install/Can.pm create mode 100644 inc/Module/Install/Fetch.pm create mode 100644 inc/Module/Install/Makefile.pm create mode 100644 inc/Module/Install/Metadata.pm create mode 100644 inc/Module/Install/RTx.pm create mode 100644 inc/Module/Install/Win32.pm create mode 100644 inc/Module/Install/WriteAll.pm create mode 100644 lib/RT/Authen/OpenID.pm diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..941c21a --- /dev/null +++ b/MANIFEST @@ -0,0 +1,15 @@ +html/Callbacks/OpenID/autohandler/Auth +html/Callbacks/OpenID/Elements/Login/Default +inc/Module/Install.pm +inc/Module/Install/Base.pm +inc/Module/Install/Can.pm +inc/Module/Install/Fetch.pm +inc/Module/Install/Makefile.pm +inc/Module/Install/Metadata.pm +inc/Module/Install/RTx.pm +inc/Module/Install/Win32.pm +inc/Module/Install/WriteAll.pm +lib/RT/Authen/OpenID.pm +Makefile.PL +MANIFEST This list of files +META.yml diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..c4ecb9c --- /dev/null +++ b/META.yml @@ -0,0 +1,13 @@ +name: RT-Authen-OpenID +version: 0.01 +abstract: Allows RT to do authentication via a service which supports the OpenID API +author: Artur Bergman +license: GPL version 2 +distribution_type: module +requires: + Net::OpenID::Consumer: 0 +no_index: + directory: + - html + - inc +generated_by: Module::Install version 0.34 diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..c8451a7 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,15 @@ +use inc::Module::Install; + +RTx('RT-Authen-OpenID'); + +name ('RT-Authen-OpenID'); +abstract ('Allows RT to do authentication via a service which supports the OpenID API'); +author ('Artur Bergman and Jesse Vincent '); +version_from ('lib/RT/Authen/OpenID.pm'); +license ('GPL version 2'); + +requires ('Net::OpenID::Consumer'); +requires ('LWPx::ParanoidAgent'); +requires ('Cache::FileCache'); + +&WriteAll; diff --git a/html/Callbacks/OpenID/Elements/Login/Default b/html/Callbacks/OpenID/Elements/Login/Default new file mode 100644 index 0000000..a4f9783 --- /dev/null +++ b/html/Callbacks/OpenID/Elements/Login/Default @@ -0,0 +1,13 @@ +<%init> +return unless ($RT::EnableOpenId); + +
+

<&|/l&>Have an OpenID? Log in with it and have a look around.

+
+ <&|/l&>OpenID: + + + +
+ +
diff --git a/html/Callbacks/OpenID/autohandler/Auth b/html/Callbacks/OpenID/autohandler/Auth new file mode 100644 index 0000000..b2c858b --- /dev/null +++ b/html/Callbacks/OpenID/autohandler/Auth @@ -0,0 +1,95 @@ +<%INIT> +return unless ($RT::EnableOpenId); +use Net::OpenID::Consumer; +use LWPx::ParanoidAgent; +use Cache::FileCache; + +my $openid_url = ref( $ARGS{openid} ) ? $ARGS{openid}->[0] : $ARGS{openid}; +my $user; +my $check_url; + +# Livejournal misencodes responses... +if ($ARGS{'openid.sig'}) { +my $sig = $m->cgi_object->param('openid.sig') ||''; +$sig =~ s/ /+/g; +$m->cgi_object->param( 'openid.sig' => $sig ); +} + + +my $root_user = RT::User->new($RT::SystemUser); +my $csr = Net::OpenID::Consumer->new( + ua => LWPx::ParanoidAgent->new, + args => \%ARGS, + cache => Cache::FileCache->new, + consumer_secret => $RT::DatabasePassword, + required_root => $RT::WebURL, +); + + +if ($openid_url) { + if ( my $claimed_identity = $csr->claimed_identity("$openid_url")) { + $check_url = $claimed_identity->check_url( + return_to => $RT::WebURL, + delayed_return => 1, + trust_root => $RT::WebURL, + ); + RT::Interface::Web::Redirect($check_url); + } else { + $RT::Logger->error("OpenID login failure for $openid_url code $csr->{last_errcode} error $csr->{last_errtext}"); + # we should end up skipping the rest now + } +} +if ( $ARGS{"openid.mode"} ) { + if ( my $setup_url = $csr->user_setup_url ) { + + # redirect/link/popup user to $setup_url + RT::Interface::Web::Redirect($setup_url); + } elsif ( $csr->user_cancel ) { + } elsif ( my $vident = $csr->verified_identity ) { + $user = $vident->url; + } else { + die ( "Error validating identity: " . $csr->err ); + } +} + +# if the user isn't logged in and we got credentials from OpenID, load them +if ( ( !$session{'CurrentUser'} ) && ($user) ) { + + # set a global user so we know elsewhere we're using OpenID for auth + $session{'OpenID'} = $user; + + # OpenID has verified that the user has control of this e-mail address, + # so it's okay to use it to get a valid RT user + + # we've got a valid user, so try to load + $session{'CurrentUser'} = RT::CurrentUser->new(); + $session{'CurrentUser'}->LoadByCols( Name => $user ); + $session{'CurrentUser'}->{'OpenID'} = 1; + if ( $session{'CurrentUser'}->id ) { + $RT::Logger->info($session{'CurrentUser'}->Name ." logged in with openid"); + } else { + my $UserObj = RT::User->new($RT::SystemUser); + my ( $id, $msg ) = $UserObj->Create( + Name => $user, + + #RealName => $user->{'name'}, + #EmailAddress => $user->{'email'}, + Privileged => 0, + ); + $RT::Logger->info($user ." attempted an account creation with OpenID: $msg"); + if ( $UserObj->id ) { + + # created the user, now load them as the current user + $session{'CurrentUser'}->Load( $UserObj->id ); + $session{'i'}++; + # redirect the user to their preference page to add more info + RT::Interface::Web::Redirect( $RT::WebURL . '/User/Prefs.html' ); + } else { + + # we couldn't create the user. abort abort abort! + delete $session{'CurrentUser'}; + die( loc( "Cannot create user: [_1]", $msg ) ); + } + } +} + diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm new file mode 100644 index 0000000..2134488 --- /dev/null +++ b/inc/Module/Install.pm @@ -0,0 +1,171 @@ +#line 1 "inc/Module/Install.pm - /usr/share/perl5/Module/Install.pm" +# $File: //depot/cpan/Module-Install/lib/Module/Install.pm $ $Author: autrijus $ +# $Revision: #68 $ $Change: 2285 $ $DateTime: 2004/07/01 03:16:20 $ vim: expandtab shiftwidth=4 + +package Module::Install; +$VERSION = '0.34'; + +die << "." unless $INC{join('/', inc => split(/::/, __PACKAGE__)).'.pm'}; +Please invoke ${\__PACKAGE__} with: + + use inc::${\__PACKAGE__}; + +not: + + use ${\__PACKAGE__}; + +. + +use strict 'vars'; +use Cwd (); +use File::Find (); +use File::Path (); + +@inc::Module::Install::ISA = 'Module::Install'; + +#line 131 + +sub import { + my $class = shift; + my $self = $class->new(@_); + + if (not -f $self->{file}) { + require "$self->{path}/$self->{dispatch}.pm"; + File::Path::mkpath("$self->{prefix}/$self->{author}"); + $self->{admin} = + "$self->{name}::$self->{dispatch}"->new(_top => $self); + $self->{admin}->init; + @_ = ($class, _self => $self); + goto &{"$self->{name}::import"}; + } + + *{caller(0) . "::AUTOLOAD"} = $self->autoload; + + # Unregister loader and worker packages so subdirs can use them again + delete $INC{"$self->{file}"}; + delete $INC{"$self->{path}.pm"}; +} + +#line 158 + +sub autoload { + my $self = shift; + my $caller = caller; + + my $cwd = Cwd::cwd(); + my $sym = "$caller\::AUTOLOAD"; + + $sym->{$cwd} = sub { + my $pwd = Cwd::cwd(); + if (my $code = $sym->{$pwd}) { + goto &$code unless $cwd eq $pwd; # delegate back to parent dirs + } + $$sym =~ /([^:]+)$/ or die "Cannot autoload $caller"; + unshift @_, ($self, $1); + goto &{$self->can('call')} unless uc($1) eq $1; + }; +} + +#line 183 + +sub new { + my ($class, %args) = @_; + + return $args{_self} if $args{_self}; + + $args{dispatch} ||= 'Admin'; + $args{prefix} ||= 'inc'; + $args{author} ||= '.author'; + $args{bundle} ||= 'inc/BUNDLES'; + + $class =~ s/^\Q$args{prefix}\E:://; + $args{name} ||= $class; + $args{version} ||= $class->VERSION; + + unless ($args{path}) { + $args{path} = $args{name}; + $args{path} =~ s!::!/!g; + } + $args{file} ||= "$args{prefix}/$args{path}.pm"; + + bless(\%args, $class); +} + +#line 212 + +sub call { + my $self = shift; + my $method = shift; + my $obj = $self->load($method) or return; + + unshift @_, $obj; + goto &{$obj->can($method)}; +} + +#line 227 + +sub load { + my ($self, $method) = @_; + + $self->load_extensions( + "$self->{prefix}/$self->{path}", $self + ) unless $self->{extensions}; + + foreach my $obj (@{$self->{extensions}}) { + return $obj if $obj->can($method); + } + + my $admin = $self->{admin} or die << "END"; +The '$method' method does not exist in the '$self->{prefix}' path! +Please remove the '$self->{prefix}' directory and run $0 again to load it. +END + + my $obj = $admin->load($method, 1); + push @{$self->{extensions}}, $obj; + + $obj; +} + +#line 257 + +sub load_extensions { + my ($self, $path, $top_obj) = @_; + + unshift @INC, $self->{prefix} + unless grep { $_ eq $self->{prefix} } @INC; + + local @INC = ($path, @INC); + foreach my $rv ($self->find_extensions($path)) { + my ($file, $pkg) = @{$rv}; + next if $self->{pathnames}{$pkg}; + + eval { require $file; 1 } or (warn($@), next); + $self->{pathnames}{$pkg} = delete $INC{$file}; + push @{$self->{extensions}}, $pkg->new( _top => $top_obj ); + } +} + +#line 281 + +sub find_extensions { + my ($self, $path) = @_; + my @found; + + File::Find::find(sub { + my $file = $File::Find::name; + return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is; + return if $1 eq $self->{dispatch}; + + $file = "$self->{path}/$1.pm"; + my $pkg = "$self->{name}::$1"; $pkg =~ s!/!::!g; + push @found, [$file, $pkg]; + }, $path) if -d $path; + + @found; +} + +1; + +__END__ + +#line 619 diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm new file mode 100644 index 0000000..7199d96 --- /dev/null +++ b/inc/Module/Install/Base.pm @@ -0,0 +1,57 @@ +#line 1 "inc/Module/Install/Base.pm - /usr/share/perl5/Module/Install/Base.pm" +# $File: //depot/cpan/Module-Install/lib/Module/Install/Base.pm $ $Author: autrijus $ +# $Revision: #10 $ $Change: 1847 $ $DateTime: 2003/12/31 23:14:54 $ vim: expandtab shiftwidth=4 + +package Module::Install::Base; + +#line 31 + +sub new { + my ($class, %args) = @_; + + foreach my $method (qw(call load)) { + *{"$class\::$method"} = sub { + +shift->_top->$method(@_); + } unless defined &{"$class\::$method"}; + } + + bless(\%args, $class); +} + +#line 49 + +sub AUTOLOAD { + my $self = shift; + goto &{$self->_top->autoload}; +} + +#line 60 + +sub _top { $_[0]->{_top} } + +#line 71 + +sub admin { + my $self = shift; + $self->_top->{admin} or Module::Install::Base::FakeAdmin->new; +} + +sub is_admin { + my $self = shift; + $self->admin->VERSION; +} + +sub DESTROY {} + +package Module::Install::Base::FakeAdmin; + +my $Fake; +sub new { $Fake ||= bless(\@_, $_[0]) } +sub AUTOLOAD {} +sub DESTROY {} + +1; + +__END__ + +#line 115 diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm new file mode 100644 index 0000000..7815e45 --- /dev/null +++ b/inc/Module/Install/Can.pm @@ -0,0 +1,41 @@ +#line 1 "inc/Module/Install/Can.pm - /usr/share/perl5/Module/Install/Can.pm" +# $File: //depot/cpan/Module-Install/lib/Module/Install/Can.pm $ $Author: autrijus $ +# $Revision: #6 $ $Change: 1840 $ $DateTime: 2003/12/28 19:42:02 $ vim: expandtab shiftwidth=4 + +package Module::Install::Can; +use Module::Install::Base; @ISA = qw(Module::Install::Base); +$VERSION = '0.01'; + +use strict; +use Config (); +use File::Spec (); +use ExtUtils::MakeMaker (); + +# check if we can run some command +sub can_run { + my ($self, $cmd) = @_; + + my $_cmd = $cmd; + return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd)); + + for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') { + my $abs = File::Spec->catfile($dir, $_[1]); + return $abs if (-x $abs or $abs = MM->maybe_command($abs)); + } + + return; +} + +sub can_cc { + my $self = shift; + my @chunks = split(/ /, $Config::Config{cc}) or return; + + # $Config{cc} may contain args; try to find out the program part + while (@chunks) { + return $self->can_run("@chunks") || (pop(@chunks), next); + } + + return; +} + +1; diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm new file mode 100644 index 0000000..7e9e612 --- /dev/null +++ b/inc/Module/Install/Fetch.pm @@ -0,0 +1,89 @@ +#line 1 "inc/Module/Install/Fetch.pm - /usr/share/perl5/Module/Install/Fetch.pm" +# $File: //depot/cpan/Module-Install/lib/Module/Install/Fetch.pm $ $Author: autrijus $ +# $Revision: #8 $ $Change: 1374 $ $DateTime: 2003/03/18 11:50:15 $ vim: expandtab shiftwidth=4 + +package Module::Install::Fetch; +use Module::Install::Base; @ISA = qw(Module::Install::Base); + +$VERSION = '0.01'; + +sub get_file { + my ($self, %args) = @_; + my ($scheme, $host, $path, $file) = + $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; + + if ($scheme eq 'http' and !eval { require LWP::Simple; 1 }) { + $args{url} = $args{ftp_url} + or (warn("LWP support unavailable!\n"), return); + ($scheme, $host, $path, $file) = + $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; + } + + $|++; + print "Fetching '$file' from $host... "; + + unless (eval { require Socket; Socket::inet_aton($host) }) { + warn "'$host' resolve failed!\n"; + return; + } + + return unless $scheme eq 'ftp' or $scheme eq 'http'; + + require Cwd; + my $dir = Cwd::getcwd(); + chdir $args{local_dir} or return if exists $args{local_dir}; + + if (eval { require LWP::Simple; 1 }) { + LWP::Simple::mirror($args{url}, $file); + } + elsif (eval { require Net::FTP; 1 }) { eval { + # use Net::FTP to get past firewall + my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600); + $ftp->login("anonymous", 'anonymous@example.com'); + $ftp->cwd($path); + $ftp->binary; + $ftp->get($file) or (warn("$!\n"), return); + $ftp->quit; + } } + elsif (my $ftp = $self->can_run('ftp')) { eval { + # no Net::FTP, fallback to ftp.exe + require FileHandle; + my $fh = FileHandle->new; + + local $SIG{CHLD} = 'IGNORE'; + unless ($fh->open("|$ftp -n")) { + warn "Couldn't open ftp: $!\n"; + chdir $dir; return; + } + + my @dialog = split(/\n/, << "."); +open $host +user anonymous anonymous\@example.com +cd $path +binary +get $file $file +quit +. + foreach (@dialog) { $fh->print("$_\n") } + $fh->close; + } } + else { + warn "No working 'ftp' program available!\n"; + chdir $dir; return; + } + + unless (-f $file) { + warn "Fetching failed: $@\n"; + chdir $dir; return; + } + + return if exists $args{size} and -s $file != $args{size}; + system($args{run}) if exists $args{run}; + unlink($file) if $args{remove}; + + print(((!exists $args{check_for} or -e $args{check_for}) + ? "done!" : "failed! ($!)"), "\n"); + chdir $dir; return !$?; +} + +1; diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm new file mode 100644 index 0000000..4b81205 --- /dev/null +++ b/inc/Module/Install/Makefile.pm @@ -0,0 +1,146 @@ +#line 1 "inc/Module/Install/Makefile.pm - /usr/share/perl5/Module/Install/Makefile.pm" +# $File: //depot/cpan/Module-Install/lib/Module/Install/Makefile.pm $ $Author: autrijus $ +# $Revision: #53 $ $Change: 1847 $ $DateTime: 2003/12/31 23:14:54 $ vim: expandtab shiftwidth=4 + +package Module::Install::Makefile; +use Module::Install::Base; @ISA = qw(Module::Install::Base); + +$VERSION = '0.01'; + +use strict 'vars'; +use vars '$VERSION'; + +use ExtUtils::MakeMaker (); + +sub Makefile { $_[0] } + +sub prompt { + shift; + goto &ExtUtils::MakeMaker::prompt; +} + +sub makemaker_args { + my $self = shift; + my $args = ($self->{makemaker_args} ||= {}); + %$args = ( %$args, @_ ) if @_; + $args; +} + +sub clean_files { + my $self = shift; + my $clean = $self->makemaker_args->{clean} ||= {}; + %$clean = ( + %$clean, + FILES => join(" ", grep length, $clean->{FILES}, @_), + ); +} + +sub libs { + my $self = shift; + my $libs = ref $_[0] ? shift : [shift]; + $self->makemaker_args( LIBS => $libs ); +} + +sub inc { + my $self = shift; + $self->makemaker_args( INC => shift ); +} + +sub write { + my $self = shift; + die "&Makefile->write() takes no arguments\n" if @_; + + my $args = $self->makemaker_args; + + $args->{DISTNAME} = $self->name; + $args->{NAME} = $self->module_name || $self->name || $self->determine_NAME($args); + $args->{VERSION} = $self->version || $self->determine_VERSION($args); + $args->{NAME} =~ s/-/::/g; + + if ($] >= 5.005) { + $args->{ABSTRACT} = $self->abstract; + $args->{AUTHOR} = $self->author; + } + if ( eval($ExtUtils::MakeMaker::VERSION) >= 6.10 ) { + $args->{NO_META} = 1; + } + if ( eval($ExtUtils::MakeMaker::VERSION) > 6.17 ) { + $args->{SIGN} = 1 if $self->sign; + } + delete $args->{SIGN} unless $self->is_admin; + + # merge both kinds of requires into prereq_pm + my $prereq = ($args->{PREREQ_PM} ||= {}); + %$prereq = ( %$prereq, map { @$_ } map { @$_ } grep $_, + ($self->build_requires, $self->requires) ); + + # merge both kinds of requires into prereq_pm + my $dir = ($args->{DIR} ||= []); + if ($self->bundles) { + push @$dir, map "$_->[1]", @{$self->bundles}; + delete $prereq->{$_->[0]} for @{$self->bundles}; + } + + if (my $perl_version = $self->perl_version) { + eval "use $perl_version; 1" + or die "ERROR: perl: Version $] is installed, ". + "but we need version >= $perl_version"; + } + + my %args = map {($_ => $args->{$_})} grep {defined($args->{$_})} keys %$args; + + if ($self->admin->preop) { + $args{dist} = $self->admin->preop; + } + + ExtUtils::MakeMaker::WriteMakefile(%args); + + $self->fix_up_makefile(); +} + +sub fix_up_makefile { + my $self = shift; + my $top_class = ref($self->_top) || ''; + my $top_version = $self->_top->VERSION || ''; + + my $preamble = $self->preamble + ? "# Preamble by $top_class $top_version\n" . $self->preamble + : ''; + my $postamble = "# Postamble by $top_class $top_version\n" . + ($self->postamble || ''); + + open MAKEFILE, '< Makefile' or die $!; + my $makefile = do { local $/; }; + close MAKEFILE; + + $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /; + $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g; + $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g; + + $makefile =~ s/^(FULLPERL = .*)/$1 -Iinc/m; + $makefile =~ s/^(PERL = .*)/$1 -Iinc/m; + + open MAKEFILE, '> Makefile' or die $!; + print MAKEFILE "$preamble$makefile$postamble"; + close MAKEFILE; +} + +sub preamble { + my ($self, $text) = @_; + $self->{preamble} = $text . $self->{preamble} if defined $text; + $self->{preamble}; +} + +sub postamble { + my ($self, $text) = @_; + + $self->{postamble} ||= $self->admin->postamble; + $self->{postamble} .= $text if defined $text; + $self->{postamble} +} + +1; + +__END__ + +#line 276 diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm new file mode 100644 index 0000000..3386476 --- /dev/null +++ b/inc/Module/Install/Metadata.pm @@ -0,0 +1,190 @@ +#line 1 "inc/Module/Install/Metadata.pm - /usr/share/perl5/Module/Install/Metadata.pm" +# $File: //depot/cpan/Module-Install/lib/Module/Install/Metadata.pm $ $Author: autrijus $ +# $Revision: #32 $ $Change: 1885 $ $DateTime: 2004/03/11 05:55:27 $ vim: expandtab shiftwidth=4 + +package Module::Install::Metadata; +use Module::Install::Base; @ISA = qw(Module::Install::Base); + +$VERSION = '0.04'; + +use strict 'vars'; +use vars qw($VERSION); + +sub Meta { shift } + +my @scalar_keys = qw( + name module_name version abstract author license + distribution_type sign perl_version +); +my @tuple_keys = qw(build_requires requires recommends bundles); + +foreach my $key (@scalar_keys) { + *$key = sub { + my $self = shift; + return $self->{'values'}{$key} unless @_; + $self->{'values'}{$key} = shift; + return $self; + }; +} + +foreach my $key (@tuple_keys) { + *$key = sub { + my $self = shift; + return $self->{'values'}{$key} unless @_; + my @rv; + while (@_) { + my $module = shift or last; + my $version = shift || 0; + if ($module eq 'perl') { + $version =~ s{^(\d+)\.(\d+)\.(\d+)} + {$1 + $2/1_000 + $3/1_000_000}e; + $self->perl_version($version); + next; + } + my $rv = [$module, $version]; + push @{$self->{'values'}{$key}}, $rv; + push @rv, $rv; + } + return @rv; + }; +} + +sub features { + my $self = shift; + while (my ($name, $mods) = splice(@_, 0, 2)) { + my $count = 0; + push @{$self->{'values'}{'features'}}, ($name => [ + map { (++$count % 2 and ref($_) and ($count += $#$_)) ? @$_ : $_ } @$mods + ] ); + } + return @{$self->{'values'}{'features'}}; +} + +sub no_index { + my $self = shift; + my $type = shift; + push @{$self->{'values'}{'no_index'}{$type}}, @_ if $type; + return $self->{'values'}{'no_index'}; +} + +sub _dump { + my $self = shift; + my $package = ref($self->_top); + my $version = $self->_top->VERSION; + my %values = %{$self->{'values'}}; + + delete $values{sign}; + if (my $perl_version = delete $values{perl_version}) { + # Always canonical to three-dot version + $perl_version =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2), int($3))}e + if $perl_version >= 5.006; + $values{requires} = [ + [perl => $perl_version], + @{$values{requires}||[]}, + ]; + } + + warn "No license specified, setting license = 'unknown'\n" + unless $values{license}; + + $values{license} ||= 'unknown'; + $values{distribution_type} ||= 'module'; + $values{name} ||= do { + my $name = $values{module_name}; + $name =~ s/::/-/g; + $name; + } if $values{module_name}; + + if ($values{name} =~ /::/) { + my $name = $values{name}; + $name =~ s/::/-/g; + die "Error in name(): '$values{name}' should be '$name'!\n"; + } + + my $dump = ''; + foreach my $key (@scalar_keys) { + $dump .= "$key: $values{$key}\n" if exists $values{$key}; + } + foreach my $key (@tuple_keys) { + next unless exists $values{$key}; + $dump .= "$key:\n"; + foreach (@{$values{$key}}) { + $dump .= " $_->[0]: $_->[1]\n"; + } + } + + if (my $no_index = $values{no_index}) { + push @{$no_index->{'directory'}}, 'inc'; + require YAML; + local $YAML::UseHeader = 0; + $dump .= YAML::Dump({ no_index => $no_index}); + } + else { + $dump .= << "META"; +no_index: + directory: + - inc +META + } + + $dump .= "generated_by: $package version $version\n"; + return $dump; +} + +sub read { + my $self = shift; + $self->include_deps( 'YAML', 0 ); + require YAML; + my $data = YAML::LoadFile( 'META.yml' ); + # Call methods explicitly in case user has already set some values. + while ( my ($key, $value) = each %$data ) { + next unless $self->can( $key ); + if (ref $value eq 'HASH') { + while (my ($module, $version) = each %$value) { + $self->$key( $module => $version ); + } + } + else { + $self->$key( $value ); + } + } + return $self; +} + +sub write { + my $self = shift; + return $self unless $self->is_admin; + + META_NOT_OURS: { + local *FH; + if (open FH, "META.yml") { + while () { + last META_NOT_OURS if /^generated_by: Module::Install\b/; + } + return $self if -s FH; + } + } + + warn "Writing META.yml\n"; + open META, "> META.yml" or warn "Cannot write to META.yml: $!"; + print META $self->_dump; + close META; + return $self; +} + +sub version_from { + my ($self, $version_from) = @_; + require ExtUtils::MM_Unix; + $self->version(ExtUtils::MM_Unix->parse_version($version_from)); +} + +sub abstract_from { + my ($self, $abstract_from) = @_; + require ExtUtils::MM_Unix; + $self->abstract( + bless( { DISTNAME => $self->name }, 'ExtUtils::MM_Unix') + ->parse_abstract($abstract_from) + ); +} + +1; diff --git a/inc/Module/Install/RTx.pm b/inc/Module/Install/RTx.pm new file mode 100644 index 0000000..a991bca --- /dev/null +++ b/inc/Module/Install/RTx.pm @@ -0,0 +1,158 @@ +#line 1 "inc/Module/Install/RTx.pm - /usr/share/perl5/Module/Install/RTx.pm" +package Module::Install::RTx; +use Module::Install::Base; @ISA = qw(Module::Install::Base); + +$Module::Install::RTx::VERSION = '0.11'; + +use strict; +use FindBin; +use File::Glob (); +use File::Basename (); + +sub RTx { + my ($self, $name) = @_; + my $RTx = 'RTx'; + $RTx = $1 if $name =~ s/^(\w+)-//; + my $fname = $name; + $fname =~ s!-!/!g; + + $self->name("$RTx-$name") + unless $self->name; + $self->abstract("RT $name Extension") + unless $self->abstract; + $self->version_from (-e "$name.pm" ? "$name.pm" : "lib/$RTx/$fname.pm") + unless $self->version; + + my @prefixes = (qw(/opt /usr/local /home /usr /sw )); + my $prefix = $ENV{PREFIX}; + @ARGV = grep { /PREFIX=(.*)/ ? (($prefix = $1), 0) : 1 } @ARGV; + + if ($prefix) { + $RT::LocalPath = $prefix; + $INC{'RT.pm'} = "$RT::LocalPath/lib/RT.pm"; + } + else { + local @INC = ( + @INC, + $ENV{RTHOME} ? ($ENV{RTHOME}, "$ENV{RTHOME}/lib") : (), + map {( "$_/rt3/lib", "$_/lib/rt3", "$_/lib" )} grep $_, @prefixes + ); + until ( eval { require RT; $RT::LocalPath } ) { + warn "Cannot find the location of RT.pm that defines \$RT::LocalPath in: @INC\n"; + $_ = $self->prompt("Path to your RT.pm:") or exit; + push @INC, $_, "$_/rt3/lib", "$_/lib/rt3"; + } + } + + my $lib_path = File::Basename::dirname($INC{'RT.pm'}); + print "Using RT configurations from $INC{'RT.pm'}:\n"; + + $RT::LocalVarPath ||= $RT::VarPath; + $RT::LocalPoPath ||= $RT::LocalLexiconPath; + $RT::LocalHtmlPath ||= $RT::MasonComponentRoot; + + my %path; + my $with_subdirs = $ENV{WITH_SUBDIRS}; + @ARGV = grep { /WITH_SUBDIRS=(.*)/ ? (($with_subdirs = $1), 0) : 1 } @ARGV; + my %subdirs = map { $_ => 1 } split(/\s*,\s*/, $with_subdirs); + + foreach (qw(bin etc html po sbin var)) { + next unless -d "$FindBin::Bin/$_"; + next if %subdirs and !$subdirs{$_}; + $self->no_index( directory => $_ ); + + no strict 'refs'; + my $varname = "RT::Local" . ucfirst($_) . "Path"; + $path{$_} = ${$varname} || "$RT::LocalPath/$_"; + } + + $path{$_} .= "/$name" for grep $path{$_}, qw(etc po var); + my $args = join(', ', map "q($_)", %path); + $path{lib} = "$RT::LocalPath/lib" unless %subdirs and !$subdirs{'lib'}; + print "./$_\t=> $path{$_}\n" for sort keys %path; + + if (my @dirs = map { (-D => $_) } grep $path{$_}, qw(bin html sbin)) { + my @po = map { (-o => $_) } grep -f, File::Glob::bsd_glob("po/*.po"); + $self->postamble(<< ".") if @po; +lexicons :: +\t\$(NOECHO) \$(PERL) -MLocale::Maketext::Extract::Run=xgettext -e \"xgettext(qw(@dirs @po))\" +. + } + + my $postamble = << "."; +install :: +\t\$(NOECHO) \$(PERL) -MExtUtils::Install -e \"install({$args})\" +. + + if ($path{var} and -d $RT::MasonDataDir) { + my ($uid, $gid) = (stat($RT::MasonDataDir))[4, 5]; + $postamble .= << "."; +\t\$(NOECHO) chown -R $uid:$gid $path{var} +. + } + + my %has_etc; + if (File::Glob::bsd_glob("$FindBin::Bin/etc/schema.*")) { + # got schema, load factory module + $has_etc{schema}++; + $self->load('RTxFactory'); + $self->postamble(<< "."); +factory :: +\t\$(NOECHO) \$(PERL) -Ilib -I"$lib_path" -Minc::Module::Install -e"RTxFactory(qw($RTx $name))" + +dropdb :: +\t\$(NOECHO) \$(PERL) -Ilib -I"$lib_path" -Minc::Module::Install -e"RTxFactory(qw($RTx $name drop))" + +. + } + if (File::Glob::bsd_glob("$FindBin::Bin/etc/acl.*")) { + $has_etc{acl}++; + } + if (-e 'etc/initialdata') { + $has_etc{initialdata}++; + } + + $self->postamble("$postamble\n"); + if (%subdirs and !$subdirs{'lib'}) { + $self->makemaker_args( + PM => { "" => "" }, + ) + } + else { + $self->makemaker_args( INSTALLSITELIB => "$RT::LocalPath/lib" ); + } + + if (%has_etc) { + $self->load('RTxInitDB'); + print "For first-time installation, type 'make initdb'.\n"; + my $initdb = ''; + $initdb .= <<"." if $has_etc{schema}; +\t\$(NOECHO) \$(PERL) -Ilib -I"$lib_path" -Minc::Module::Install -e"RTxInitDB(qw(schema))" +. + $initdb .= <<"." if $has_etc{acl}; +\t\$(NOECHO) \$(PERL) -Ilib -I"$lib_path" -Minc::Module::Install -e"RTxInitDB(qw(acl))" +. + $initdb .= <<"." if $has_etc{initialdata}; +\t\$(NOECHO) \$(PERL) -Ilib -I"$lib_path" -Minc::Module::Install -e"RTxInitDB(qw(insert))" +. + $self->postamble("initdb ::\n$initdb\n"); + $self->postamble("initialize-database ::\n$initdb\n"); + } +} + +sub RTxInit { + unshift @INC, substr(delete($INC{'RT.pm'}), 0, -5) if $INC{'RT.pm'}; + require RT; + RT::LoadConfig(); + RT::ConnectToDatabase(); + + die "Cannot load RT" unless $RT::Handle and $RT::DatabaseType; +} + +1; + +__END__ + +#line 221 + +#line 242 diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm new file mode 100644 index 0000000..6efc3b2 --- /dev/null +++ b/inc/Module/Install/Win32.pm @@ -0,0 +1,66 @@ +#line 1 "inc/Module/Install/Win32.pm - /usr/share/perl5/Module/Install/Win32.pm" +# $File: //depot/cpan/Module-Install/lib/Module/Install/Win32.pm $ $Author: autrijus $ +# $Revision: #9 $ $Change: 1789 $ $DateTime: 2003/11/11 01:22:54 $ vim: expandtab shiftwidth=4 + +package Module::Install::Win32; +use Module::Install::Base; @ISA = qw(Module::Install::Base); + +$VERSION = '0.02'; + +use strict; + +# determine if the user needs nmake, and download it if needed +sub check_nmake { + my $self = shift; + $self->load('can_run'); + $self->load('get_file'); + + require Config; + return unless ( + $Config::Config{make} and + $Config::Config{make} =~ /^nmake\b/i and + $^O eq 'MSWin32' and + !$self->can_run('nmake') + ); + + print "The required 'nmake' executable not found, fetching it...\n"; + + require File::Basename; + my $rv = $self->get_file( + url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe', + ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe', + local_dir => File::Basename::dirname($^X), + size => 51928, + run => 'Nmake15.exe /o > nul', + check_for => 'Nmake.exe', + remove => 1, + ); + + if (!$rv) { + die << '.'; + +------------------------------------------------------------------------------- + +Since you are using Microsoft Windows, you will need the 'nmake' utility +before installation. It's available at: + + http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe + or + ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe + +Please download the file manually, save it to a directory in %PATH% (e.g. +C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to +that directory, and run "Nmake15.exe" from there; that will create the +'nmake.exe' file needed by this module. + +You may then resume the installation process described in README. + +------------------------------------------------------------------------------- +. + } +} + +1; + +__END__ + diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm new file mode 100644 index 0000000..76d9621 --- /dev/null +++ b/inc/Module/Install/WriteAll.pm @@ -0,0 +1,39 @@ +#line 1 "inc/Module/Install/WriteAll.pm - /usr/share/perl5/Module/Install/WriteAll.pm" +# $File: //depot/cpan/Module-Install/lib/Module/Install/WriteAll.pm $ $Author: autrijus $ +# $Revision: #3 $ $Change: 1885 $ $DateTime: 2004/03/11 05:55:27 $ vim: expandtab shiftwidth=4 + +package Module::Install::WriteAll; +use Module::Install::Base; @ISA = qw(Module::Install::Base); + +sub WriteAll { + my $self = shift; + my %args = ( + meta => 1, + sign => 0, + inline => 0, + check_nmake => 1, + @_ + ); + + $self->sign(1) if $args{sign}; + $self->Meta->write if $args{meta}; + $self->admin->WriteAll(%args) if $self->is_admin; + + if ($0 =~ /Build.PL$/i) { + $self->Build->write; + } + else { + $self->check_nmake if $args{check_nmake}; + $self->makemaker_args( PL_FILES => {} ) + unless $self->makemaker_args->{'PL_FILES'}; + + if ($args{inline}) { + $self->Inline->write; + } + else { + $self->Makefile->write; + } + } +} + +1; diff --git a/lib/RT/Authen/OpenID.pm b/lib/RT/Authen/OpenID.pm new file mode 100644 index 0000000..118a8b5 --- /dev/null +++ b/lib/RT/Authen/OpenID.pm @@ -0,0 +1,15 @@ + +=head1 COPYRIGHT + +This extension is Copyright (C) 2005,2007 Best Practical Solutions, LLC. +Portions of this extension are Copyright (C) 2006 Artur Bergman + +It is freely redistributable under the terms of version 2 of the GNU GPL. + +=cut + +package RT::Authen::OpenID; + +our $VERSION = '0.02'; + +1;