From 601b41083cf7c2186ecce70ec07aebdb9310edd6 Mon Sep 17 00:00:00 2001 From: Buchan Milne Date: Tue, 26 Oct 2010 14:51:48 +0000 Subject: Clean up repo --- Changes | 4 + META.yml | 31 +++ Makefile.PL | 25 ++ README | 1 + catdap.yml | 125 +++++++++ lib/CatDap.pm | 91 ++++++ lib/CatDap/Controller/Root.pm | 69 +++++ lib/CatDap/Controller/register.pm | 150 ++++++++++ lib/CatDap/Controller/user.pm | 335 +++++++++++++++++++++++ lib/CatDap/I18N/af.po | 119 ++++++++ lib/CatDap/I18N/fr.po | 133 +++++++++ lib/CatDap/I18N/messages.pot | 129 +++++++++ lib/CatDap/Model/Proxy.pm | 40 +++ lib/CatDap/Model/User.pm | 40 +++ lib/CatDap/View/Email.pm | 33 +++ lib/CatDap/View/TT.pm | 36 +++ root/favicon.ico | Bin 0 -> 2551 bytes root/index.tt | 34 +++ root/register/check.tt | 4 + root/register/complete.tt | 16 ++ root/register/index.tt | 45 +++ root/static/images/btn_120x50_built.png | Bin 0 -> 3826 bytes root/static/images/btn_120x50_built_shadow.png | Bin 0 -> 3681 bytes root/static/images/btn_120x50_powered.png | Bin 0 -> 3862 bytes root/static/images/btn_120x50_powered_shadow.png | Bin 0 -> 3673 bytes root/static/images/btn_88x31_built.png | Bin 0 -> 2517 bytes root/static/images/btn_88x31_built_shadow.png | Bin 0 -> 2274 bytes root/static/images/btn_88x31_powered.png | Bin 0 -> 2542 bytes root/static/images/btn_88x31_powered_shadow.png | Bin 0 -> 2304 bytes root/static/images/catalyst_logo.png | Bin 0 -> 13710 bytes script/catdap_cgi.pl | 30 ++ script/catdap_create.pl | 57 ++++ script/catdap_fastcgi.pl | 47 ++++ script/catdap_i18n.sh | 16 ++ script/catdap_server.pl | 60 ++++ script/catdap_test.pl | 40 +++ t/01app.t | 10 + t/02pod.t | 10 + t/03podcoverage.t | 10 + t/controller_register.t | 9 + t/controller_user.t | 9 + t/model_Proxy.t | 6 + t/model_User.t | 6 + t/view_Email.t | 7 + t/view_TT.t | 7 + 45 files changed, 1784 insertions(+) create mode 100644 Changes create mode 100644 META.yml create mode 100644 Makefile.PL create mode 100644 README create mode 100644 catdap.yml create mode 100644 lib/CatDap.pm create mode 100644 lib/CatDap/Controller/Root.pm create mode 100644 lib/CatDap/Controller/register.pm create mode 100644 lib/CatDap/Controller/user.pm create mode 100644 lib/CatDap/I18N/af.po create mode 100644 lib/CatDap/I18N/fr.po create mode 100644 lib/CatDap/I18N/messages.pot create mode 100644 lib/CatDap/Model/Proxy.pm create mode 100644 lib/CatDap/Model/User.pm create mode 100644 lib/CatDap/View/Email.pm create mode 100644 lib/CatDap/View/TT.pm create mode 100644 root/favicon.ico create mode 100644 root/index.tt create mode 100644 root/register/check.tt create mode 100644 root/register/complete.tt create mode 100644 root/register/index.tt create mode 100644 root/static/images/btn_120x50_built.png create mode 100644 root/static/images/btn_120x50_built_shadow.png create mode 100644 root/static/images/btn_120x50_powered.png create mode 100644 root/static/images/btn_120x50_powered_shadow.png create mode 100644 root/static/images/btn_88x31_built.png create mode 100644 root/static/images/btn_88x31_built_shadow.png create mode 100644 root/static/images/btn_88x31_powered.png create mode 100644 root/static/images/btn_88x31_powered_shadow.png create mode 100644 root/static/images/catalyst_logo.png create mode 100755 script/catdap_cgi.pl create mode 100755 script/catdap_create.pl create mode 100755 script/catdap_fastcgi.pl create mode 100755 script/catdap_i18n.sh create mode 100755 script/catdap_server.pl create mode 100755 script/catdap_test.pl create mode 100644 t/01app.t create mode 100644 t/02pod.t create mode 100644 t/03podcoverage.t create mode 100644 t/controller_register.t create mode 100644 t/controller_user.t create mode 100644 t/model_Proxy.t create mode 100644 t/model_User.t create mode 100644 t/view_Email.t create mode 100644 t/view_TT.t diff --git a/Changes b/Changes new file mode 100644 index 0000000..c7443e8 --- /dev/null +++ b/Changes @@ -0,0 +1,4 @@ +This file documents the revision history for Perl extension CatDap. + +0.01 2010-10-11 09:11:10 + - initial revision, generated by Catalyst diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..13c53f4 --- /dev/null +++ b/META.yml @@ -0,0 +1,31 @@ +--- +abstract: 'Catalyst based application' +author: + - 'Buchan Milne' +build_requires: + ExtUtils::MakeMaker: 6.42 + Test::More: 0.88 +configure_requires: + ExtUtils::MakeMaker: 6.42 +distribution_type: module +generated_by: 'Module::Install version 0.95' +license: perl +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: 1.4 +name: CatDap +no_index: + directory: + - inc + - t +requires: + Catalyst::Action::RenderView: 0 + Catalyst::Plugin::ConfigLoader: 0 + Catalyst::Plugin::Static::Simple: 0 + Catalyst::Runtime: 5.80022 + Config::General: 0 + Moose: 0 + namespace::autoclean: 0 +resources: + license: http://dev.perl.org/licenses/ +version: 0.01 diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..7a4561c --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +# IMPORTANT: if you delete this file your app will not work as +# expected. You have been warned. +use inc::Module::Install; +use Module::Install::Catalyst; # Complain loudly if you don't have + # Catalyst::Devel installed or haven't said + # 'make dist' to create a standalone tarball. + +name 'CatDap'; +all_from 'lib/CatDap.pm'; + +requires 'Catalyst::Runtime' => '5.80022'; +requires 'Catalyst::Plugin::ConfigLoader'; +requires 'Catalyst::Plugin::Static::Simple'; +requires 'Catalyst::Action::RenderView'; +requires 'Moose'; +requires 'namespace::autoclean'; +requires 'Config::General'; # This should reflect the config file format you've chosen + # See Catalyst::Plugin::ConfigLoader for supported formats +test_requires 'Test::More' => '0.88'; +catalyst; + +install_script glob('script/*.pl'); +auto_install; +WriteAll; diff --git a/README b/README new file mode 100644 index 0000000..6fcdf85 --- /dev/null +++ b/README @@ -0,0 +1 @@ +Run script/catdap_server.pl to test the application. diff --git a/catdap.yml b/catdap.yml new file mode 100644 index 0000000..81e214f --- /dev/null +++ b/catdap.yml @@ -0,0 +1,125 @@ +# This is the default configuration for CatDap. You should not need to +# modify it, unless you actually want to fix some default behaviour +# that is configured below +# +# For site-specific configuration, copy this file (catdap.yml) to +# have a _local suffix (catdap_local.yml) and make your changes there. +# Note that you only need to keep configuration sections that differ, +# the rest will be inherited + +name: CatDap +default_view: TT + +Model::Proxy: + base: ou=People,dc=mageia,dc=org + dn: cn=catdap,ou=System Accounts,dc=mageai,dc=org + password: FIXME + host: ldap.mageia.org + start_tls: 1 + +# dn and password should not be required here, we rebind with credentials +# from the authenticated user using Model::LDAP::FromAuthentication +Model::User: + base: ou=People,dc=mageia,dc=org + host: ldap.mageia.org + start_tls: 1 + +authentication: + default_realm: ldap + realms: + ldap: + credential: + class: Password + password_field: password + password_type: self_check + store: + class: LDAP + ldap_server: 'ldap.mageia.org' + start_tls: 1 + binddn: cn=catdap,ou=System Accounts,dc=mageai,dc=org + bindpw: FIXME + user_basedn: "ou=people,dc=mageia,dc=org" + user_filter: '(&(objectClass=inetOrgPerson)(uid=%s))' + user_scope: 'one' + user_field: 'uid' + use_roles: 1 + role_basedn: 'ou=group,dc=mageia,dc=org' + role_scope: 'one' + role_field: 'cn' + role_value: 'uid' + +Controller::User: +# Attributes that the user can edit. Attributes present but not listed here +# will be show (if not in skip_attrs), but the form will not allow editing. +# Note that the actual access contols should be implemented on the LDAP side, +# that is where they belong, or you are being inconsistent if users have other +# means to access LDAP + editable_attrs: + - cn + - sn + - givenName + - mail + - mobile + - roomNumber + - secretary + - mailForwardingAddress + +# Currently not used, we only respect editable_attrs + uneditable_attrs: + - uid + # - uidNumber + # - gidNumber + - homeDirectory + - host + - manager + - krb5PrincipalName +# List of attributes which are not displayed at all in the user view + skip_attrs: + - objectClass + - krb5Key + - sambaMungedDial + - sambaPasswordHistory + - userPassword + - sambaLMPassword + - sambaNTPassword + - sambaPwdMustChange + - sambaSID + - sambaPrimaryGroupSID + - sambaAcctFlags + - sambaPwdCanChange + - sambaPwdLastSet + - sambaKickOffTime + - sambaUserWorkstations + - sambaLogonTime + - krb5KeyVersionNumber + - krb5PasswordEnd + - krb5MaxLife + - krb5MaxRenew + - krb5KDCFlags + - shadowLastChange + - shadowWarning + - shadowMax + - shadowMin + - shadowInactive + - shadowExpire + - shadowFlag + +Plugin::Captcha: + new: + gd_font: giant + width: 100 + height: 40 + lines: 7 + + create: + - normal + - rect + + particle: + - 100 + + gd_font: giant + +Plugin::Session: + expires: 600 + diff --git a/lib/CatDap.pm b/lib/CatDap.pm new file mode 100644 index 0000000..d9a37a9 --- /dev/null +++ b/lib/CatDap.pm @@ -0,0 +1,91 @@ +package CatDap; +use Moose; +use namespace::autoclean; + +use Catalyst::Runtime 5.80; + +# Set flags and add plugins for the application +# +# -Debug: activates the debug mode for very useful log messages +# ConfigLoader: will load the configuration from a Config::General file in the +# application's home directory +# Static::Simple: will serve static files from the application's root +# directory + +use Catalyst qw/ + -Debug + ConfigLoader + Static::Simple + Session + Session::State::Cookie + Session::Store::File + Captcha + Authentication + I18N +/; + +extends 'Catalyst'; + +our $VERSION = '0.01'; +$VERSION = eval $VERSION; + +# Configure the application. +# +# Note that settings in catdap.conf (or other external +# configuration file that you set up manually) take precedence +# over this when using ConfigLoader. Thus configuration +# details given here can function as a default configuration, +# with an external configuration file acting as an override for +# local deployment. + +__PACKAGE__->config( + name => 'CatDap', + # Disable deprecated behavior needed by old applications + disable_component_resolution_regex_fallback => 1, +); + +sub begin : Private { + my ( $self, $c ) = @_; + + my $locale = $c->request->param('locale'); + $c->response->headers->push_header( 'Vary' => 'Accept-Language' ); # hmm vary and param? + $c->languages( $locale ? [ $locale ] : undef ); +} + + +#c->languages(['af']); + +# Start the application +__PACKAGE__->setup(); + + +=head1 NAME + +CatDap - Catalyst based application + +=head1 SYNOPSIS + + script/catdap_server.pl + +=head1 DESCRIPTION + +[enter your description here] + +=head1 SEE ALSO + +L, L + +=head1 AUTHOR + +Buchan Milne + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +sub end : ActionClass('RenderView') {} + +1; diff --git a/lib/CatDap/Controller/Root.pm b/lib/CatDap/Controller/Root.pm new file mode 100644 index 0000000..550cd61 --- /dev/null +++ b/lib/CatDap/Controller/Root.pm @@ -0,0 +1,69 @@ +package CatDap::Controller::Root; +use Moose; +use namespace::autoclean; + +BEGIN { extends 'Catalyst::Controller' } + +# +# Sets the actions in this controller to be registered with no prefix +# so they function identically to actions created in MyApp.pm +# +__PACKAGE__->config(namespace => ''); + +=head1 NAME + +CatDap::Controller::Root - Root Controller for CatDap + +=head1 DESCRIPTION + +[enter your description here] + +=head1 METHODS + +=head2 index + +The root page (/) + +=cut + +sub index :Path :Args(0) { + my ( $self, $c ) = @_; + + # Hello World + #$c->response->body( $c->welcome_message ); +} + +=head2 default + +Standard 404 error page + +=cut + +sub default :Path { + my ( $self, $c ) = @_; + $c->response->body( 'Page not found' ); + $c->response->status(404); +} + +=head2 end + +Attempt to render a view, if needed. + +=cut + +sub end : ActionClass('RenderView') {} + +=head1 AUTHOR + +Buchan Milne + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/lib/CatDap/Controller/register.pm b/lib/CatDap/Controller/register.pm new file mode 100644 index 0000000..d8fc7c1 --- /dev/null +++ b/lib/CatDap/Controller/register.pm @@ -0,0 +1,150 @@ +package CatDap::Controller::register; +use Moose; +use namespace::autoclean; +use Data::Dumper; +use Email::Valid; +use Data::UUID; + +BEGIN {extends 'Catalyst::Controller'; } + +=head1 NAME + +CatDap::Controller::register - Catalyst Controller + +=head1 DESCRIPTION + +Catalyst Controller. + +=head1 METHODS + +=cut + + +=head2 index + +=cut + +sub index :Path :Args(0) : Form { + my ( $self, $c ) = @_; + + #my $form = Catalyst::Controller::HTML::FormFu->form(); + #$c->response->body('Matched CatDap::Controller::register in register.'); +} + +sub check : Local { + my ( $self, $c ) = @_; + + my %details = %{$c->request->params}; + my $username = $c->request->params->{uid}; + $username =~ s/[A-Z]/[a-z]/g; + my @errors; + $c->stash(errors => []); + # Check username, start with letter, followed by letters or numbers + if ($username !~ /^[a-z][a-z0-9_\-]*$/) { + push @errors, $c->loc('Invalid username'); + } + my $email = $c->request->params->{mail1}; + if (! Email::Valid->address($email)) { + push @errors, $c->loc('Invalid email address'); + } + if ($email ne $c->request->params->{mail2}) { + push @errors, $c->loc('Addresses do not match'); + } + if (! $c->validate_captcha($c->req->param('validate'))){ + push @errors, $c->loc('Incorrect validation text, please try again'); + } + if ($c->request->params->{gn} !~ /^\p{IsAlnum}*\z$/) { + push @errors, $c->loc('The first name supplied contains illegal characters'); + } + if ($c->request->params->{sn} !~ /^\p{IsAlnum}*\z$/) { + #push @errors, $c->loc('The') . ' ' $c->loc('surname') . ' ' . $c->loc('supplied contains unprintable characters'); + push @errors, $c->loc('The surname supplied contains illegal characters'); + } + + if (@errors gt 0) { + $c->stash(errors => \@errors); + $c->stash(template => 'register/index.tt'); + } else { + # check in LDAP now that we have validated username and email + my $mesg = $c->model('Proxy')->search("(mail=$email)"); + if ($mesg->entries ne 0) { + push @errors,$c->loc('An account already exists with this email address'); + } + $mesg = $c->model('Proxy')->search("(uid=$username)"); + if ($mesg->entries ne 0) { + my $foo = Dumper(${$c->config}{'Model::Proxy'}{'base'}); + push @errors,$c->loc('An account already exists with this username'); + #push @errors,"under base" . __PACKAGE__->config{Model::Proxy}{base}; + push @errors,$foo; + } + if (@errors gt 0) { + $c->stash(errors => \@errors); + $c->stash(template => 'register/index.tt'); + } else { + my $dn = "uid=$username,${$c->config}{'Model::Proxy'}{'base'}"; + my $ug = Data::UUID->new; + my $password = $ug->create_str(); + my $cn = $c->request->params->{gn} . " " . $c->request->params->{sn}; + $mesg = $c->model('Proxy')->add($dn, + attr => [ + objectclass => [ 'inetOrgPerson' ], + sn => $c->request->params->{sn}, + gn => $c->request->params->{gn}, + cn => $cn, + mail => $email, + pwdReset => 'TRUE', + userPassword => $password, + ] + ); + if ($mesg) { + push @errors,$mesg->error; + $c->stash(errors => \@errors); + #$c->stash(template => 'register/index.tt'); + } + #} else { + my $body; + $body .= $c->loc('Dear') . " $c->request->params->{gn},\n"; + $body .= $c->loc("Your Mageia indentity has been successfully created, but requires activation.\n"); + $body .= $c->loc("To activate your account, please follow the link below.\n"); + $body .= $c->uri_for('/user/firstlogin') . "?username=$username&key=$password"; + $c->stash->{email} = { + to => $email, + from => 'no-reply@mageia.org', + subject => $c->loc('Mageia Identity Activation'), + body => $body, + }; + + $c->forward( $c->view('Email') ); + if ( scalar( @{ $c->error } ) ) { + my $errors = join "\n",@{ $c->error }; + $c->response->body($c->loc('An error occured sending the email, but your account was created. Please try the password recovery process f you entered the correct email address: [_1]', $errors)); + $c->error(0); # Reset the error condition if you need to + } + $c->stash(template => 'register/complete.tt'); + $c->stash(message => 'Check your email'); + #} + } + } +} + +sub captcha : Local { + my ($self, $c) = @_; + return $c->create_captcha(); +} + + + +=head1 AUTHOR + +Buchan Milne + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/lib/CatDap/Controller/user.pm b/lib/CatDap/Controller/user.pm new file mode 100644 index 0000000..41fe412 --- /dev/null +++ b/lib/CatDap/Controller/user.pm @@ -0,0 +1,335 @@ +package CatDap::Controller::user; +use Moose; +use namespace::autoclean; +use Net::LDAP; +use Net::LDAP::Schema; +use Net::LDAP::Extension::SetPassword; +use Net::LDAP::Control::PasswordPolicy 0.02; +use Crypt::CBC; +use Data::Dumper; + +BEGIN {extends 'Catalyst::Controller'; } + +=head1 NAME + +CatDap::Controller::user - Catalyst Controller + +=head1 DESCRIPTION + +Catalyst Controller. + +=head1 METHODS + +=cut + +=head2 auto + +Ensure the user is logged in. In order to bind as the user, we use +CatDap::Model::User, which uses Catalyst::Model::LDAP::FromAuthentication, +which effectively requires calling $c->authenticate on every request. + +To do this, we keep the password, encrypted with blowfish, using the +(for now), first 3 octets of IPv4 request address and the session id as the key. + +So, if the user does "not exist", we authenticate them, if it succeeds we encrypt +the password and store it in the session. + +If the user is logged in, we get the encrypted password from the session, decrypt +it (we need to handle failure to decrypt it better) + +=cut + +sub auto : Private { + my ( $self, $c ) = @_; + my $cipher; + my $password; + my $mesg; + my $dn; + my $keyprefix = sprintf("%02x%02x%02x",split /\./,$c->req->address); + $c->log->info("Using $keyprefix as first part of enc key"); + if (! defined $c->user) { + $c->log->info("No session, logging user in"); + if (! $c->authenticate({ username => $c->req->param('username'), + password => $c->req->param('password') || $c->req->param('key')}) ) { + #TODO: ppolicy .... + $c->stash(errors => ['Incorrect username or password']); + $c->stash(template => 'index.tt'); + $c->forward('/index'); + $c->detach; + } else { + #if (defined $c->user->pwdReset) { + # $c->res->redirect('/user'); + #} + #$c->persist_user; + $c->log->info('Logging user in to LDAP'); + $cipher = Crypt::CBC->new( -key => $keyprefix . $c->sessionid, + -cipher => 'Blowfish' + ) or die $!; + $c->session->{enc_password} = $cipher->encrypt($c->req->param('password') || $c->req->param('key')); + $c->session->{dn} = $c->user->ldap_entry->dn; + $c->session->{user} = $c->req->param('username'); + $password = $c->req->param('password') || $c->req->param('key'); + return 1; + } + + } else { + $cipher = Crypt::CBC->new( -key => $keyprefix . $c->sessionid, + -cipher => 'Blowfish' + ) or die $!; + $password = $cipher->decrypt($c->session->{enc_password}); + $c->log->info("Re-authenticating user " . $c->session->{user}); + $c->authenticate({username => $c->session->{user},password => $password}); + $c->log->info($@) if $@; + return 1; + } + +} + +=head2 index + +=cut + +sub index :Path :Args(0) { + my ( $self, $c ) = @_; + my $cipher; + my $password; + my $mesg; + my $dn; + + if (not defined $c->user ) { + $c->stash(template => 'index.tt'); + $c->forward('/index'); + $c->detach; + } + my $schemaldap = Net::LDAP->new(${$c->config}{'Model::Proxy'}{'host'}) or warn "LDAP bind failed: $!"; + $schemaldap->start_tls if ${$c->config}{'Model::Proxy'}{'start_tls'}; + $schemaldap->bind; + my $schema = $schemaldap->schema or die ("Searching schema failed: $!"); + my $attrdef; + + my $user = $c->user->username; + my $entry; + $c->log->info("Searching for user $user"); + $mesg = $c->model('User')->search("(&(objectclass=inetOrgPerson)(uid=$user))"); + $entry = $mesg->entry; + my %mods; + my %params = %{$c->req->parameters}; + my $update = 0; + foreach my $req (keys %params) { + next if $req !~ /(.+)_new/; + my $attrname = $1; + next if $params{$attrname . '_new'} eq $params{$attrname . '_old'}; + $c->log->info("Received update request for attribute $attrname"); + $update = 1; + $attrdef = $schema->attribute($attrname) or die ("getting schema failed: $!"); + if ($$attrdef{'single-value'}) { + $entry->replace($attrname => $params{$attrname . '_new' }) or $c->log->info($!); + } else { + $entry->delete($attrname => $params{$attrname . '_old'}); + $entry->add($attrname => $params{$attrname . '_new'}); + } + if ($update) { + $mesg = $entry->update; + push @{${$c->stash}{'errors'}},$mesg->error if $mesg->code; + } + } + + + $mesg = $c->model('User')->search("(&(objectclass=inetOrgPerson)(uid=$user))"); + $c->log->info($mesg->error) if $mesg->code; + $entry = $mesg->entry; + $c->log->info($mesg->error) if $mesg->code; + + my @values; + my @attributes = $entry->attributes; + my @may; + my @addable_attrs = @attributes; + my @ocs; + my @must; + @ocs = $entry->get_value("objectClass"); + foreach my $oc (@ocs) { + foreach my $attr ($schema->must($oc)) { + push @must,$$attr{'name'} if not grep /$$attr{'name'}/,@must; + } + } + + foreach my $attr (sort @attributes) { + next if ($attr eq "objectClass"); + next if grep /$attr/,@{${$c->config}{'Controller::User'}{'skip_attrs'}}; + my @vals = $entry->get_value($attr); + $attrdef = $schema->attribute($attr) or die ("getting schema failed: $!"); + my %valhash = ( + name => $attr, + values => \@vals, + desc => $$attrdef{'desc'}, + ); + if (! grep /^$attr$/, @{${$c->config}{'Controller::User'}{'uneditable_attrs'}}) { + $valhash{'editable'} = 1; + } + if (! $$attrdef{'single-value'} && $valhash{'editable'}) { $valhash{'addable'} = 1; } + if (! grep /$attr/,@must) { $valhash{'removable'} = 1; } + push @values, \%valhash; + } + foreach my $oc (@ocs) { + foreach my $attrdef ($schema->may($oc)) { + my $attrname = $$attrdef{'name'}; + grep /$attrname/,@may or + grep /$attrname/,@attributes or + grep /$attrname/,@{${$c->config}{'Controller::User'}{'uneditable_attrs'}} or + grep /$attrname/,@{${$c->config}{'Controller::User'}{'skip_attrs'}} or + push @may, $attrname; + } + } + @may = sort @may; + $c->stash({ username => $user, + values => \@values, + attrdef => $attrdef, + may => \@may, + must => \@must, + }); +} + +sub add : Local { + my ( $self, $c) = @_; + my ($mesg,$entry,$user,$attr,$value); + $attr = $c->req->param('attribute'); + $value = $c->req->param('value'); + $user = $c->user->username; + $c->log->info("Searching for user $user"); + $mesg = $c->model('User')->search("(&(objectclass=inetOrgPerson)(uid=$user))"); + $entry = $mesg->entry; + $entry->add( $attr => $value); + $c->log->info("Adding $attr = $value to user $user"); + $entry->update; + push @{${$c->stash}{'errors'}},$mesg->error if $mesg->code; + $c->log->info($mesg->error); + $c->res->redirect('/user'); +} + +sub delete : Local : Args(2) { + my ( $self, $c, $attrname,$attrvalue) = @_; + my ($mesg,$entry,$user); + $user = $c->user->username; + $c->log->info("Searching for user $user"); + $mesg = $c->model('User')->search("(&(objectclass=inetOrgPerson)(uid=$user))"); + $entry = $mesg->entry; + $c->log->info("Deleting $attrname = $attrvalue from user $user"); + $entry->delete($attrname => $attrvalue); + $entry->update; + push @{${$c->stash}{'errors'}},$mesg->error if $mesg->code; + $c->log->info($mesg->error); + $c->res->redirect('/user'); +} + +sub password : Local { + my ( $self, $c) = @_; + my ($mesg,$newpass,$cipher); + if ( not defined $c->req->param('password') or not defined $c->req->param('newpassword1') or not defined $c->req->param('newpassword2')) { + #if ( not defined $c->req->param('newpassword1') or not defined $c->req->param('newpassword2')) { + $c->detach; + } + if ($c->req->param('newpassword1') eq $c->req->param('newpassword2')) { + $newpass = $c->req->param('newpassword1'); + } else { + push @{${$c->stash}{'errors'}},"New passwords dont match"; + } + my $pp = Net::LDAP::Control::PasswordPolicy->new; + $mesg = $c->model('User')->set_password( + oldpasswd => $c->req->param('password'), + newpasswd => $newpass, + control => [ $pp ], + ); + if ($mesg->code) { + my $perror = $mesg->error; + push @{${$c->stash}{'errors'}},"Password change failed: $perror"; + $c->detach; + } else { + # re-encrypt the new password and forward to user view + my $keyprefix = sprintf("%02x%02x%02x",split /\./,$c->req->address); + $cipher = Crypt::CBC->new( -key => $keyprefix . $c->sessionid, + -cipher => 'Blowfish' + ) or die $!; + $c->session->{enc_password} = $cipher->encrypt($newpass); + push @{${$c->stash}{'errors'}},"Password change succeeded"; + $c->res->redirect('/user'); + } + + +} + +sub firstlogin : Local { + my ( $self, $c ) = @_; + my ($mesg,$newpass,$cipher); + + if (! $c->authenticate({ + username => $c->req->param('username'), + password => $c->req->param('key')}) ) { + $c->stash(errors => ['An error occurred']); + $c->res->redirect('/user'); + } + + if ( not defined $c->req->param('newpassword1') or not defined $c->req->param('newpassword2')) { + $c->detach; + } + if ($c->req->param('newpassword1') eq $c->req->param('newpassword2')) { + $newpass = $c->req->param('newpassword1'); + } else { + push @{${$c->stash}{'errors'}},"New passwords dont match"; + } + my $pp = Net::LDAP::Control::PasswordPolicy->new; + $mesg = $c->model('User')->set_password( + #oldpasswd => $c->req->param('password'), + newpasswd => $newpass, + control => [ $pp ], + ); + if ($mesg->code) { + my $perror = $mesg->error; + push @{${$c->stash}{'errors'}},"Password change failed: $perror"; + $c->detach; + } else { + # re-encrypt the new password and forward to user view + my $keyprefix = sprintf("%02x%02x%02x",split /\./,$c->req->address); + $cipher = Crypt::CBC->new( -key => $keyprefix . $c->sessionid, + -cipher => 'Blowfish' + ) or die $!; + $c->session->{enc_password} = $cipher->encrypt($newpass); + push @{${$c->stash}{'errors'}},"Password change succeeded"; + $c->res->redirect('/user'); + } + +} + +sub login : Local { + my ( $self, $c ) = @_; + if ($c->authenticate({ username => $c->req->param('username'), + password => $c->req->param('password') || $c->req->param('key')}) ) { + $c->res->redirect('/user'); + } else { + #TODO: ppolicy .... + $c->stash(errors => ['Incorrect username or password']); + $c->stash(template => 'index.tt'); + $c->forward('/index'); + } + return $c->error; +} + +sub logout : Local { + my ( $self, $c ) = @_; + $c->delete_session; + $c->res->redirect('/'); +} + +=head1 AUTHOR + +Buchan Milne + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/lib/CatDap/I18N/af.po b/lib/CatDap/I18N/af.po new file mode 100644 index 0000000..7181fbe --- /dev/null +++ b/lib/CatDap/I18N/af.po @@ -0,0 +1,119 @@ +#: lib/CatDap/Controller/register.pm:51 +msgid "Addresses do not match" +msgstr "Die addresse verskil" + +#: lib/CatDap/Controller/register.pm:71 +msgid "An account already exists with this email address" +msgstr "'n Rekening met hierde epos adres bestaan reeds" + +#: lib/CatDap/Controller/register.pm:76 +msgid "An account already exists with this username" +msgstr "'n Rekening met hierdie gebruikersnaam bestaan reeds" + +#. ($errors) +#: lib/CatDap/Controller/register.pm:120 +msgid "" +"An error occured sending the email, but your account was created. Please try " +"the password recovery process f you entered the correct email address: %1" +msgstr "" +"Daar was 'n fout met die stuur van die aktiverings epos, maar jou rekening " +"is geskep. Probeer die wagwoord herwinnings proses as die epos adres korrek " +"was" + +#: root/register/complete.tt:16 +msgid "Check your mail for activation instructions" +msgstr "Kyk jou epos vir aktiverings instruksies" + +#: root/register/index.tt:34 +msgid "Confirm Email address" +msgstr "Bevestig epos adres" + +#: lib/CatDap/Controller/register.pm:106 +msgid "Dear" +msgstr "Liewe" + +#: root/register/index.tt:30 +msgid "Email address" +msgstr "Epos adres" + +#: root/register/index.tt:22 +msgid "First name" +msgstr "Voornaam" + +#: lib/CatDap/Controller/register.pm:54 +msgid "Incorrect validation text, please try again" +msgstr "Inkorrekte teks van die prentjie, probeer weer" + +#: lib/CatDap/Controller/register.pm:48 +msgid "Invalid email address" +msgstr "Ongeldige epos adres" + +#: lib/CatDap/Controller/register.pm:44 +msgid "Invalid username" +msgstr "Ongeldige gebruikersnaam" + +#: root/index.tt:28 root/index.tt:6 +msgid "Login" +msgstr "Teken in" + +#: lib/CatDap/Controller/register.pm:113 +msgid "Mageia Identity Activation" +msgstr "Mageia Identiteit Aktivering" + +#: root/index.tt:22 +msgid "Password" +msgstr "Wagwoord" + +#: root/index.tt:29 root/register/index.tt:43 root/register/index.tt:6 +msgid "Register" +msgstr "Registreer" + +#: root/register/complete.tt:6 +msgid "Registration completed" +msgstr "Registrasie voltooi" + +#: root/register/complete.tt:15 +msgid "Registration was successful." +msgstr "Registrasie was suksesvol" + +#: root/register/index.tt:26 +msgid "Surname" +msgstr "Van" + +#: lib/CatDap/Controller/register.pm:60 +msgid "The" +msgstr "Die" + +#: lib/CatDap/Controller/register.pm:57 +msgid "The first name supplied contains illegal characters" +msgstr "Die verskafte noemnaam sluit ongeldige karakters in" + +#: lib/CatDap/Controller/register.pm:61 +msgid "The surname supplied contains illegal characters" +msgstr "Die verskafte van sluit ondeldige karakters in" + +#: lib/CatDap/Controller/register.pm:107 +msgid "To activate your account, please follow the link below.\n" +msgstr "Om U rekening te aktiveer, volg asseblief die volgende skakel.\n" + +#: root/index.tt:18 root/register/index.tt:18 +msgid "Username" +msgstr "Gebruikersnaam" + +#: lib/CatDap/Controller/register.pm:106 +msgid "" +"Your Mageia indentity has been successfully created, but requires " +"activation.\n" +msgstr "" + +#: root/index.tt:28 +msgid "or" +msgstr "of" + +#: lib/CatDap/Controller/register.pm:60 +msgid "supplied contains unprintable characters" +msgstr "verskaf sluit in ongeldige karakters" + +#: lib/CatDap/Controller/register.pm:60 +msgid "surname" +msgstr "Van" diff --git a/lib/CatDap/I18N/fr.po b/lib/CatDap/I18N/fr.po new file mode 100644 index 0000000..56305a3 --- /dev/null +++ b/lib/CatDap/I18N/fr.po @@ -0,0 +1,133 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" +"PO-Revision-Date: 2010-10-19 21:07+0100\n" +"Last-Translator: Michael Scherer \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: lib/CatDap/Controller/register.pm:51 +msgid "Addresses do not match" +msgstr "Les adresses ne correspondent pas" + +#: lib/CatDap/Controller/register.pm:71 +msgid "An account already exists with this email address" +msgstr "" + +#: lib/CatDap/Controller/register.pm:76 +msgid "An account already exists with this username" +msgstr "Un compte existe déjà pour ce nom d'utilisateur" + +#. ($errors) +#: lib/CatDap/Controller/register.pm:120 +msgid "An error occured sending the email, but your account was created. Please try the password recovery process f you entered the correct email address: %1" +msgstr "" + +#: root/register/complete.tt:16 +msgid "Check your mail for activation instructions" +msgstr "" + +#: root/register/index.tt:34 +msgid "Confirm Email address" +msgstr "" + +#: lib/CatDap/Controller/register.pm:106 +msgid "Dear" +msgstr "Cher(e)" + +#: root/register/index.tt:30 +msgid "Email address" +msgstr "Adresse mail" + +#: root/register/index.tt:22 +msgid "First name" +msgstr "" + +#: lib/CatDap/Controller/register.pm:54 +msgid "Incorrect validation text, please try again" +msgstr "" + +#: lib/CatDap/Controller/register.pm:48 +msgid "Invalid email address" +msgstr "Adresse mail invalide" + +#: lib/CatDap/Controller/register.pm:44 +msgid "Invalid username" +msgstr "Nom d'utilisateur invalide" + +#: root/index.tt:33 +#: root/index.tt:6 +msgid "Login" +msgstr "Login" + +#: lib/CatDap/Controller/register.pm:113 +msgid "Mageia Identity Activation" +msgstr "Activation de l'identité Mageia" + +#: root/index.tt:27 +msgid "Password" +msgstr "Mot de passe" + +#: root/index.tt:34 +#: root/register/index.tt:43 +#: root/register/index.tt:6 +msgid "Register" +msgstr "S'enregistrer" + +#: root/register/complete.tt:6 +msgid "Registration completed" +msgstr "" + +#: root/register/complete.tt:15 +msgid "Registration was successful." +msgstr "" + +#: root/register/index.tt:26 +msgid "Surname" +msgstr "Surnom" + +#: lib/CatDap/Controller/register.pm:60 +msgid "The" +msgstr "" + +#: lib/CatDap/Controller/register.pm:57 +msgid "The first name supplied contains illegal characters" +msgstr "" + +#: lib/CatDap/Controller/register.pm:61 +msgid "The surname supplied contains illegal characters" +msgstr "" + +#: lib/CatDap/Controller/register.pm:107 +msgid "To activate your account, please follow the link below.\n" +msgstr "Pour activer votre compte, merci de suivre le lien ci dessous." + +#: root/index.tt:23 +#: root/register/index.tt:18 +msgid "Username" +msgstr "Nom d'utilisateur" + +#: lib/CatDap/Controller/register.pm:106 +msgid "Your Mageia indentity has been successfully created, but requires activation.\n" +msgstr "" + +#: root/index.tt:33 +msgid "or" +msgstr "ou" + +#: lib/CatDap/Controller/register.pm:60 +msgid "supplied contains unprintable characters" +msgstr "" + +#: lib/CatDap/Controller/register.pm:60 +msgid "surname" +msgstr "" + diff --git a/lib/CatDap/I18N/messages.pot b/lib/CatDap/I18N/messages.pot new file mode 100644 index 0000000..d4bddea --- /dev/null +++ b/lib/CatDap/I18N/messages.pot @@ -0,0 +1,129 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: lib/CatDap/Controller/register.pm:51 +msgid "Addresses do not match" +msgstr "" + +#: lib/CatDap/Controller/register.pm:71 +msgid "An account already exists with this email address" +msgstr "" + +#: lib/CatDap/Controller/register.pm:76 +msgid "An account already exists with this username" +msgstr "" + +#. ($errors) +#: lib/CatDap/Controller/register.pm:120 +msgid "An error occured sending the email, but your account was created. Please try the password recovery process f you entered the correct email address: %1" +msgstr "" + +#: root/register/complete.tt:16 +msgid "Check your mail for activation instructions" +msgstr "" + +#: root/register/index.tt:34 +msgid "Confirm Email address" +msgstr "" + +#: lib/CatDap/Controller/register.pm:106 +msgid "Dear" +msgstr "" + +#: root/register/index.tt:30 +msgid "Email address" +msgstr "" + +#: root/register/index.tt:22 +msgid "First name" +msgstr "" + +#: lib/CatDap/Controller/register.pm:54 +msgid "Incorrect validation text, please try again" +msgstr "" + +#: lib/CatDap/Controller/register.pm:48 +msgid "Invalid email address" +msgstr "" + +#: lib/CatDap/Controller/register.pm:44 +msgid "Invalid username" +msgstr "" + +#: root/index.tt:28 root/index.tt:6 +msgid "Login" +msgstr "" + +#: lib/CatDap/Controller/register.pm:113 +msgid "Mageia Identity Activation" +msgstr "" + +#: root/index.tt:22 +msgid "Password" +msgstr "" + +#: root/index.tt:29 root/register/index.tt:43 root/register/index.tt:6 +msgid "Register" +msgstr "" + +#: root/register/complete.tt:6 +msgid "Registration completed" +msgstr "" + +#: root/register/complete.tt:15 +msgid "Registration was successful." +msgstr "" + +#: root/register/index.tt:26 +msgid "Surname" +msgstr "" + +#: lib/CatDap/Controller/register.pm:60 +msgid "The" +msgstr "" + +#: lib/CatDap/Controller/register.pm:57 +msgid "The first name supplied contains illegal characters" +msgstr "" + +#: lib/CatDap/Controller/register.pm:61 +msgid "The surname supplied contains illegal characters" +msgstr "" + +#: lib/CatDap/Controller/register.pm:107 +msgid "To activate your account, please follow the link below.\n" +msgstr "" + +#: root/index.tt:18 root/register/index.tt:18 +msgid "Username" +msgstr "" + +#: lib/CatDap/Controller/register.pm:106 +msgid "Your Mageia indentity has been successfully created, but requires activation.\n" +msgstr "" + +#: root/index.tt:28 +msgid "or" +msgstr "" + +#: lib/CatDap/Controller/register.pm:60 +msgid "supplied contains unprintable characters" +msgstr "" + +#: lib/CatDap/Controller/register.pm:60 +msgid "surname" +msgstr "" diff --git a/lib/CatDap/Model/Proxy.pm b/lib/CatDap/Model/Proxy.pm new file mode 100644 index 0000000..ba7e5dc --- /dev/null +++ b/lib/CatDap/Model/Proxy.pm @@ -0,0 +1,40 @@ +package CatDap::Model::Proxy; + +use strict; +use warnings; +use base qw/Catalyst::Model::LDAP/; + +__PACKAGE__->config( + host => 'ldap.mageia.org', + base => 'ou=People,dc=mageia,dc=org', + dn => '', + password => '', + start_tls => 0, + start_tls_options => { verify => 'require' }, + options => {}, # Options passed to search +); + +=head1 NAME + +CatDap::Model::Proxy - LDAP Catalyst model component + +=head1 SYNOPSIS + +See L. + +=head1 DESCRIPTION + +LDAP Catalyst model component. + +=head1 AUTHOR + +Buchan Milne + +=head1 LICENSE + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +1; diff --git a/lib/CatDap/Model/User.pm b/lib/CatDap/Model/User.pm new file mode 100644 index 0000000..2d726fc --- /dev/null +++ b/lib/CatDap/Model/User.pm @@ -0,0 +1,40 @@ +package CatDap::Model::User; + +use strict; +use warnings; +#use base qw/Catalyst::Model::LDAP/; +use Moose; +use namespace::autoclean; +extends 'Catalyst::Model::LDAP::FromAuthentication'; + +__PACKAGE__->config( + base => 'ou=People,dc=mageia,dc=org', + dn => 'cn=dummy', + password => 'dummy', +); + + +=head1 NAME + +CatDap::Model::User - LDAP Catalyst model component + +=head1 SYNOPSIS + +See L. + +=head1 DESCRIPTION + +LDAP Catalyst model component. + +=head1 AUTHOR + +Buchan Milne + +=head1 LICENSE + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +1; diff --git a/lib/CatDap/View/Email.pm b/lib/CatDap/View/Email.pm new file mode 100644 index 0000000..5e7e96d --- /dev/null +++ b/lib/CatDap/View/Email.pm @@ -0,0 +1,33 @@ +package CatDap::View::Email; + +use strict; +use base 'Catalyst::View::Email'; + +__PACKAGE__->config( + stash_key => 'email' +); + +=head1 NAME + +CatDap::View::Email - Email View for CatDap + +=head1 DESCRIPTION + +View for sending email from CatDap. + +=head1 AUTHOR + +Buchan Milne + +=head1 SEE ALSO + +L + +=head1 LICENSE + +This library is free software, you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +1; diff --git a/lib/CatDap/View/TT.pm b/lib/CatDap/View/TT.pm new file mode 100644 index 0000000..0cd6acb --- /dev/null +++ b/lib/CatDap/View/TT.pm @@ -0,0 +1,36 @@ +package CatDap::View::TT; + +use strict; +use warnings; + +use base 'Catalyst::View::TT'; + +__PACKAGE__->config( + TEMPLATE_EXTENSION => '.tt', + render_die => 1, +); + +=head1 NAME + +CatDap::View::TT - TT View for CatDap + +=head1 DESCRIPTION + +TT View for CatDap. + +=head1 SEE ALSO + +L + +=head1 AUTHOR + +Buchan Milne + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +1; diff --git a/root/favicon.ico b/root/favicon.ico new file mode 100644 index 0000000..5ad723d Binary files /dev/null and b/root/favicon.ico differ diff --git a/root/index.tt b/root/index.tt new file mode 100644 index 0000000..3b43806 --- /dev/null +++ b/root/index.tt @@ -0,0 +1,34 @@ +[% MACRO l(text, args) BLOCK; + c.localize(text, args); +END; %] + + +

[% l('Login') %]

+ + +[% FOREACH error IN errors %] +[% error %]
+[% END %] +
+ +
+ + + + + + + + + + + + + + +
[% l('Username') %]
[% l('Password') %]
+ [% l('or') %] + [% l('Register') %] +
+ + diff --git a/root/register/check.tt b/root/register/check.tt new file mode 100644 index 0000000..aab8e33 --- /dev/null +++ b/root/register/check.tt @@ -0,0 +1,4 @@ +

Success

+

+[% message %] + diff --git a/root/register/complete.tt b/root/register/complete.tt new file mode 100644 index 0000000..a4f07e2 --- /dev/null +++ b/root/register/complete.tt @@ -0,0 +1,16 @@ +[% MACRO l(text, args) BLOCK; + c.localize(text, args); +END; %] + + +

[% l('Registration completed') %]

+ + +[% FOREACH error IN errors %] +[% error %]
+[% END %] +
+ +

+[% l('Registration was successful.') %] +[% l('Check your mail for activation instructions') %] diff --git a/root/register/index.tt b/root/register/index.tt new file mode 100644 index 0000000..f509316 --- /dev/null +++ b/root/register/index.tt @@ -0,0 +1,45 @@ +[% MACRO l(text, args) BLOCK; + c.localize(text, args); +END; %] + + +

[% l('Register') %]

+ + +[% FOREACH error IN errors %] +[% error %]
+[% END %] +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
[% l('Username') %]
[% l('First name') %]
[% l('Surname') %]
[% l('Email address') %]
[% l('Confirm Email address') %]
+
+
diff --git a/root/static/images/btn_120x50_built.png b/root/static/images/btn_120x50_built.png new file mode 100644 index 0000000..c709fd6 Binary files /dev/null and b/root/static/images/btn_120x50_built.png differ diff --git a/root/static/images/btn_120x50_built_shadow.png b/root/static/images/btn_120x50_built_shadow.png new file mode 100644 index 0000000..15142fe Binary files /dev/null and b/root/static/images/btn_120x50_built_shadow.png differ diff --git a/root/static/images/btn_120x50_powered.png b/root/static/images/btn_120x50_powered.png new file mode 100644 index 0000000..7249b47 Binary files /dev/null and b/root/static/images/btn_120x50_powered.png differ diff --git a/root/static/images/btn_120x50_powered_shadow.png b/root/static/images/btn_120x50_powered_shadow.png new file mode 100644 index 0000000..e6876c0 Binary files /dev/null and b/root/static/images/btn_120x50_powered_shadow.png differ diff --git a/root/static/images/btn_88x31_built.png b/root/static/images/btn_88x31_built.png new file mode 100644 index 0000000..007b5db Binary files /dev/null and b/root/static/images/btn_88x31_built.png differ diff --git a/root/static/images/btn_88x31_built_shadow.png b/root/static/images/btn_88x31_built_shadow.png new file mode 100644 index 0000000..ccf4624 Binary files /dev/null and b/root/static/images/btn_88x31_built_shadow.png differ diff --git a/root/static/images/btn_88x31_powered.png b/root/static/images/btn_88x31_powered.png new file mode 100644 index 0000000..8f0cd9f Binary files /dev/null and b/root/static/images/btn_88x31_powered.png differ diff --git a/root/static/images/btn_88x31_powered_shadow.png b/root/static/images/btn_88x31_powered_shadow.png new file mode 100644 index 0000000..aa776fa Binary files /dev/null and b/root/static/images/btn_88x31_powered_shadow.png differ diff --git a/root/static/images/catalyst_logo.png b/root/static/images/catalyst_logo.png new file mode 100644 index 0000000..21f1cac Binary files /dev/null and b/root/static/images/catalyst_logo.png differ diff --git a/script/catdap_cgi.pl b/script/catdap_cgi.pl new file mode 100755 index 0000000..dea0834 --- /dev/null +++ b/script/catdap_cgi.pl @@ -0,0 +1,30 @@ +#!/usr/bin/env perl + +use Catalyst::ScriptRunner; +Catalyst::ScriptRunner->run('CatDap', 'CGI'); + +1; + +=head1 NAME + +catdap_cgi.pl - Catalyst CGI + +=head1 SYNOPSIS + +See L + +=head1 DESCRIPTION + +Run a Catalyst application as a cgi script. + +=head1 AUTHORS + +Catalyst Contributors, see Catalyst.pm + +=head1 COPYRIGHT + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + diff --git a/script/catdap_create.pl b/script/catdap_create.pl new file mode 100755 index 0000000..18c0239 --- /dev/null +++ b/script/catdap_create.pl @@ -0,0 +1,57 @@ +#!/usr/bin/env perl + +use strict; +use warnings; + +use Catalyst::ScriptRunner; +Catalyst::ScriptRunner->run('CatDap', 'Create'); + +1; + +=head1 NAME + +catdap_create.pl - Create a new Catalyst Component + +=head1 SYNOPSIS + +catdap_create.pl [options] model|view|controller name [helper] [options] + + Options: + --force don't create a .new file where a file to be created exists + --mechanize use Test::WWW::Mechanize::Catalyst for tests if available + --help display this help and exits + + Examples: + catdap_create.pl controller My::Controller + catdap_create.pl -mechanize controller My::Controller + catdap_create.pl view My::View + catdap_create.pl view MyView TT + catdap_create.pl view TT TT + catdap_create.pl model My::Model + catdap_create.pl model SomeDB DBIC::Schema MyApp::Schema create=dynamic\ + dbi:SQLite:/tmp/my.db + catdap_create.pl model AnotherDB DBIC::Schema MyApp::Schema create=static\ + dbi:Pg:dbname=foo root 4321 + + See also: + perldoc Catalyst::Manual + perldoc Catalyst::Manual::Intro + +=head1 DESCRIPTION + +Create a new Catalyst Component. + +Existing component files are not overwritten. If any of the component files +to be created already exist the file will be written with a '.new' suffix. +This behavior can be suppressed with the C<-force> option. + +=head1 AUTHORS + +Catalyst Contributors, see Catalyst.pm + +=head1 COPYRIGHT + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/script/catdap_fastcgi.pl b/script/catdap_fastcgi.pl new file mode 100755 index 0000000..110db29 --- /dev/null +++ b/script/catdap_fastcgi.pl @@ -0,0 +1,47 @@ +#!/usr/bin/env perl + +use Catalyst::ScriptRunner; +Catalyst::ScriptRunner->run('CatDap', 'FastCGI'); + +1; + +=head1 NAME + +catdap_fastcgi.pl - Catalyst FastCGI + +=head1 SYNOPSIS + +catdap_fastcgi.pl [options] + + Options: + -? -help display this help and exits + -l --listen Socket path to listen on + (defaults to standard input) + can be HOST:PORT, :PORT or a + filesystem path + -n --nproc specify number of processes to keep + to serve requests (defaults to 1, + requires -listen) + -p --pidfile specify filename for pid file + (requires -listen) + -d --daemon daemonize (requires -listen) + -M --manager specify alternate process manager + (FCGI::ProcManager sub-class) + or empty string to disable + -e --keeperr send error messages to STDOUT, not + to the webserver + +=head1 DESCRIPTION + +Run a Catalyst application as fastcgi. + +=head1 AUTHORS + +Catalyst Contributors, see Catalyst.pm + +=head1 COPYRIGHT + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/script/catdap_i18n.sh b/script/catdap_i18n.sh new file mode 100755 index 0000000..8c52d1c --- /dev/null +++ b/script/catdap_i18n.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +app=CatDap + +if [ $# -eq 0 ] +then + xgettext.pl --output=lib/$app/I18N/messages.pot --directory=lib --directory=root + for po in lib/$app/I18N/*.po + do + file=`basename $po` + loc=${file%%.po} + msgmerge --update lib/$app/I18N/$loc.po lib/$app/I18N/messages.pot + done +else + msginit --input=lib/$app/I18N/messages.pot --output=lib/$app/I18N/$1.po --locale=$1 +fi diff --git a/script/catdap_server.pl b/script/catdap_server.pl new file mode 100755 index 0000000..b75954b --- /dev/null +++ b/script/catdap_server.pl @@ -0,0 +1,60 @@ +#!/usr/bin/env perl + +BEGIN { + $ENV{CATALYST_SCRIPT_GEN} = 40; +} + +use Catalyst::ScriptRunner; +Catalyst::ScriptRunner->run('CatDap', 'Server'); + +1; + +=head1 NAME + +catdap_server.pl - Catalyst Test Server + +=head1 SYNOPSIS + +catdap_server.pl [options] + + -d --debug force debug mode + -f --fork handle each request in a new process + (defaults to false) + -? --help display this help and exits + -h --host host (defaults to all) + -p --port port (defaults to 3000) + -k --keepalive enable keep-alive connections + -r --restart restart when files get modified + (defaults to false) + -rd --restart_delay delay between file checks + (ignored if you have Linux::Inotify2 installed) + -rr --restart_regex regex match files that trigger + a restart when modified + (defaults to '\.yml$|\.yaml$|\.conf|\.pm$') + --restart_directory the directory to search for + modified files, can be set mulitple times + (defaults to '[SCRIPT_DIR]/..') + --follow_symlinks follow symlinks in search directories + (defaults to false. this is a no-op on Win32) + --background run the process in the background + --pidfile specify filename for pid file + + See also: + perldoc Catalyst::Manual + perldoc Catalyst::Manual::Intro + +=head1 DESCRIPTION + +Run a Catalyst Testserver for this application. + +=head1 AUTHORS + +Catalyst Contributors, see Catalyst.pm + +=head1 COPYRIGHT + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + diff --git a/script/catdap_test.pl b/script/catdap_test.pl new file mode 100755 index 0000000..43f9849 --- /dev/null +++ b/script/catdap_test.pl @@ -0,0 +1,40 @@ +#!/usr/bin/env perl + +use Catalyst::ScriptRunner; +Catalyst::ScriptRunner->run('CatDap', 'Test'); + +1; + +=head1 NAME + +catdap_test.pl - Catalyst Test + +=head1 SYNOPSIS + +catdap_test.pl [options] uri + + Options: + --help display this help and exits + + Examples: + catdap_test.pl http://localhost/some_action + catdap_test.pl /some_action + + See also: + perldoc Catalyst::Manual + perldoc Catalyst::Manual::Intro + +=head1 DESCRIPTION + +Run a Catalyst action from the command line. + +=head1 AUTHORS + +Catalyst Contributors, see Catalyst.pm + +=head1 COPYRIGHT + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/t/01app.t b/t/01app.t new file mode 100644 index 0000000..00299fd --- /dev/null +++ b/t/01app.t @@ -0,0 +1,10 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More; + +BEGIN { use_ok 'Catalyst::Test', 'CatDap' } + +ok( request('/')->is_success, 'Request should succeed' ); + +done_testing(); diff --git a/t/02pod.t b/t/02pod.t new file mode 100644 index 0000000..3d1bab1 --- /dev/null +++ b/t/02pod.t @@ -0,0 +1,10 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More; + +eval "use Test::Pod 1.14"; +plan skip_all => 'Test::Pod 1.14 required' if $@; +plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD}; + +all_pod_files_ok(); diff --git a/t/03podcoverage.t b/t/03podcoverage.t new file mode 100644 index 0000000..4e1c6e7 --- /dev/null +++ b/t/03podcoverage.t @@ -0,0 +1,10 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More; + +eval "use Test::Pod::Coverage 1.04"; +plan skip_all => 'Test::Pod::Coverage 1.04 required' if $@; +plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD}; + +all_pod_coverage_ok(); diff --git a/t/controller_register.t b/t/controller_register.t new file mode 100644 index 0000000..526e1a1 --- /dev/null +++ b/t/controller_register.t @@ -0,0 +1,9 @@ +use strict; +use warnings; +use Test::More; + +BEGIN { use_ok 'Catalyst::Test', 'CatDap' } +BEGIN { use_ok 'CatDap::Controller::register' } + +ok( request('/register')->is_success, 'Request should succeed' ); +done_testing(); diff --git a/t/controller_user.t b/t/controller_user.t new file mode 100644 index 0000000..f8e26a0 --- /dev/null +++ b/t/controller_user.t @@ -0,0 +1,9 @@ +use strict; +use warnings; +use Test::More; + +BEGIN { use_ok 'Catalyst::Test', 'CatDap' } +BEGIN { use_ok 'CatDap::Controller::user' } + +ok( request('/user')->is_success, 'Request should succeed' ); +done_testing(); diff --git a/t/model_Proxy.t b/t/model_Proxy.t new file mode 100644 index 0000000..c98a6db --- /dev/null +++ b/t/model_Proxy.t @@ -0,0 +1,6 @@ +use strict; +use warnings; +use Test::More tests => 2; + +use_ok('Catalyst::Test', 'CatDap'); +use_ok('CatDap::Model::Proxy'); diff --git a/t/model_User.t b/t/model_User.t new file mode 100644 index 0000000..543866c --- /dev/null +++ b/t/model_User.t @@ -0,0 +1,6 @@ +use strict; +use warnings; +use Test::More tests => 2; + +use_ok('Catalyst::Test', 'CatDap'); +use_ok('CatDap::Model::User'); diff --git a/t/view_Email.t b/t/view_Email.t new file mode 100644 index 0000000..757075d --- /dev/null +++ b/t/view_Email.t @@ -0,0 +1,7 @@ +use strict; +use warnings; +use Test::More; + +BEGIN { use_ok 'CatDap::View::Email' } + +done_testing(); diff --git a/t/view_TT.t b/t/view_TT.t new file mode 100644 index 0000000..0adc968 --- /dev/null +++ b/t/view_TT.t @@ -0,0 +1,7 @@ +use strict; +use warnings; +use Test::More; + +BEGIN { use_ok 'CatDap::View::TT' } + +done_testing(); -- cgit v1.2.1