requires 'Catalyst::View::Download::Plain';
requires 'Catalyst::View::JSON';
requires 'Catalyst::View::TT';
+requires 'Catalyst::View::Email::Template';
+## Auth:
+requires 'Catalyst::Plugin::Authentication';
+requires 'Catalyst::Plugin::Session';
+requires 'Catalyst::Plugin::Session::Store::File';
+requires 'Catalyst::Plugin::Session::State::Cookie';
+requires 'CatalystX::Controller::Auth';
+requires 'Catalyst::TraitFor::Controller::reCAPTCHA';
+requires 'LWP::Protocol::https';
+##
requires 'Moose';
requires 'TryCatch';
requires 'namespace::autoclean';
use Catalyst::Runtime 5.80;
+use Search::GIN::Extract::Class;
+use Search::GIN::Extract::Attributes;
+use Search::GIN::Extract::Multiplex;
+
# Set flags and add plugins for the application.
#
# Note that ORDERING IS IMPORTANT here as plugins are initialized in order,
ConfigLoader
Static::Simple
Unicode::Encoding
+ Authentication
+ Session
+ Session::Store::File
+ Session::State::Cookie
+ StatusMessage
+ StackTrace
/;
extends 'Catalyst';
stemmaweb->path_to( 'root', 'src' ),
],
},
+ ## kiokudb auth store testing
+ 'Plugin::Authentication' => {
+ default => {
+ credential => {
+ class => 'Password',
+ password_field => 'password',
+ password_type => 'self_check',
+ },
+ store => {
+ class => 'Model::KiokuDB',
+ model_name => 'Directory',
+ },
+ },
+ openid => {
+ credential => {
+ class => 'OpenID',
+ extensions => ['http://openid.net/srv/ax/1.0' =>
+ {
+ ns => 'ax',
+ uri => 'http://openid.net/srv/ax/1.0',
+ mode => 'fetch_request',
+ required => 'email',
+ 'type.email' => 'http://axschema.org/contact/email',
+ # type => {
+ # email => 'http://axschema.org/contact/email'
+ # }
+ }
+ ],
+ },
+ store => {
+ class => 'Model::KiokuDB',
+ model_name => 'Directory',
+ },
+ auto_create_user => 1,
+ },
+ },
+ ## Auth with CatalystX::Controller::Auth
+ 'Controller::Users' => {
+ model => 'User',
+ login_id_field => 'username',
+ login_db_field => 'username',
+ action_after_login => '/index',
+ action_after_register => '/index',
+ register_email_from => '"MyApp" <somebody@example.com>',
+ register_email_subject => 'Registration to stemmaweb',
+ register_email_template_plain => 'register-plain.tt',
+ realm => 'default',
+ login_fields => { openid => [qw/openid_identifier/],
+ default => [qw/username password remember/],
+ },
+ },
+ 'View::Email::Template' => {
+ stash_key => 'email_template',
+ },
+
+ recaptcha => {
+ pub_key => '',
+ priv_key => '',
+ },
);
# Start the application
GET /directory
-Serves a snippet of HTML that lists the available texts. Eventually this will be available texts by user.
+Serves a snippet of HTML that lists the available texts. This returns texts belonging to the logged-in user if any, otherwise it returns all public texts.
=cut
+
sub directory :Local :Args(0) {
my( $self, $c ) = @_;
my $m = $c->model('Directory');
- # TODO not used yet, will load user texts later
- my $user = $c->request->param( 'user' ) || 'ALL';
- my @textlist = $m->traditionlist();
+ my $user = $c->user_exists ? $c->user->get_object : 'public';
+ my @textlist = $m->traditionlist($user);
$c->stash->{texts} = \@textlist;
$c->stash->{template} = 'directory.tt';
}
--- /dev/null
+package stemmaweb::Controller::Users;
+use Moose;
+use namespace::autoclean;
+
+BEGIN {extends 'CatalystX::Controller::Auth'; }
+with 'Catalyst::TraitFor::Controller::reCAPTCHA';
+
+=head1 NAME
+
+stemmaweb::Controller::Users - Catalyst Controller
+
+=head1 DESCRIPTION
+
+The Users controller is based on L<CatalystX::Controller::Auth>, see
+there for most of the functionality. Any localised parts are described
+below.
+
+This controller uses L<Catalyst::TraitFor::Controller::reCAPTCHA> to
+create and check a reCaptcha form shown on the C<register> form to
+help prevent spam signups.
+
+=head1 METHODS
+
+=cut
+
+sub base :Chained('/') :PathPart('') :CaptureArgs(0)
+{
+ my ( $self, $c ) = @_;
+
+ $self->next::method( $c );
+}
+
+=head2 index
+
+The index action is not currently used.
+
+=cut
+
+sub index :Path :Args(0) {
+ my ( $self, $c ) = @_;
+
+ $c->response->body('Matched stemmaweb::Controller::Users in Users.');
+}
+
+=head2 login with openid
+
+Logging in with openid/google requires two passes through the login
+action, on the 2nd pass the C<openid-check> value is passed in when
+the openid providing webserver links the user back to the stemmaweb
+site. This adaption to the C<login> action sets the realm we are
+authenticating against to be C<openid> in this case.
+
+=cut
+
+before login => sub {
+ my($self, $c) = @_;
+ $c->req->param( realm => 'openid')
+ if $c->req->param('openid-check');
+};
+
+=head2 register with recaptcha
+
+This adapts the C<register> action to add the recaptcha HTML to the
+page, and verify the recaptcha info entered is correct when the form
+is submitted. If the recaptcha is not correct, we just redisplay the
+form with an error message.
+
+=cut
+
+before register => sub {
+ my ($self, $c) = @_;
+
+ ## Puts HTML into stash in "recaptcha" key.
+ $c->forward('captcha_get');
+
+ ## When submitting, check recaptcha passes, else re-draw form
+ if($c->req->method eq 'POST') {
+ if(!$c->forward('captcha_check')) {
+
+ ## Need these two lines to detach, so end can draw the correct template again:
+ my $form = $self->form_handler->new( active => [ $self->login_id_field, 'password', 'confirm_password' ] );
+ $c->stash( template => $self->register_template, form => $form );
+
+ $c->detach();
+ }
+ }
+};
+
+=head1 AUTHOR
+
+A clever guy
+
+=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;
--- /dev/null
+package stemmaweb::View::Email::Template;
+
+use strict;
+use base 'Catalyst::View::Email::Template';
+
+__PACKAGE__->config(
+ stash_key => 'email',
+ template_prefix => ''
+);
+
+=head1 NAME
+
+stemmaweb::View::Email::Template - Templated Email View for stemmaweb
+
+=head1 DESCRIPTION
+
+View for sending template-generated email from stemmaweb.
+
+=head1 AUTHOR
+
+A clever guy
+
+=head1 SEE ALSO
+
+L<stemmaweb>
+
+=head1 LICENSE
+
+This library is free software, you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+1;
--- /dev/null
+[% IF status_msg %]
+ <p>[% status_msg | html %]</p>
+[% END %]
+[% IF error_msg %]
+ <p class="error">[% error_msg | html %]</p>
+[% END %]
+
+[% IF form.has_errors %]
+ <p class="error">Some fields had errors:</p>
+
+ <ul class="errors">
+ [% FOREACH msg IN form.errors %]
+ <li>[% msg | html %]</li>
+ [% END %]
+ </ul>
+[% END %]
+
+ <form method="post" action="[% c.uri_for_action('/users/login').hostless | html %]" autocomplete="off">
+
+ <input type="hidden" name="realm" value="openid"/>
+ <input type="hidden" name="openid_identifier" value="https://www.google.com/accounts/o8/id"/>
+ <input type="submit" value="Sign in with Google"/>
+
+ </form>
+
+[% UNLESS c.req.param('realm') == 'openid' %]
+ <form method="post" action="[% c.uri_for_action('/users/login').hostless | html %]" autocomplete="off">
+
+ <input type="hidden" name="realm" value="default"/>
+
+ [% form.field('username').render %]
+ [% form.field('password').render %]
+ [% form.field('remember').render %]
+
+ [% form.field('submit').render %]
+
+ </form>
+[% END %]
\ No newline at end of file
--- /dev/null
+[% IF status_msg %]
+ <p>[% status_msg | html %]</p>
+[% END %]
+[% IF error_msg %]
+ <p class="error">[% error_msg | html %]</p>
+[% END %]
+
+[% IF form.has_errors %]
+ <p class="error">Some fields had errors:</p>
+
+ <ul class="errors">
+ [% FOREACH msg IN form.errors %]
+ <li>[% msg | html %]</li>
+ [% END %]
+ </ul>
+[% END %]
+
+ <form method="post" action="[% c.uri_for_action('/users/register').hostless | html %]" autocomplete="off">
+
+ [% form.field('username').render %] (email)
+ [% form.field('password').render %]
+ [% form.field('confirm_password').render %]
+
+ [% IF recaptcha_error %]
+ <p class="error">[% recaptcha_error | html %]</p>
+ [% END %]
+ [% recaptcha %]
+
+ [% form.field('submit').render %]
+
+ </form>
\ No newline at end of file
<div id="topbanner">
<h1>Stemmaweb - a collection of tools for analysis of collated texts</h1>
- <span class="mainnav"><a href="[% c.uri_for( 'about.html' ) %]">About<a> | <a href="[% c.uri_for( 'doc.html' ) %]">Help</a></span>
+ <span class="mainnav">[% IF c.user_exists %]Hello! [% c.user.get_object.email %] [% ELSE %]<a href="[% c.uri_for('/login') %]">Login</a> | <a href="[% c.uri_for('/register') %]">Register</a> | [% END %]<a href="[% c.uri_for( 'about.html' ) %]">About<a> | <a href="[% c.uri_for( 'doc.html' ) %]">Help</a></span>
</div>
<div id="directory_container">
<h2>Text directory</h2>
--- /dev/null
+Thank you for registering with Stemmaweb!
+
name = stemmaweb
<Model Directory>
dsn dbi:SQLite:dbname=db/traditions.db
-</Model>
\ No newline at end of file
+</Model>
+<Model User>
+ dsn dbi:SQLite:dbname=db/traditions.db
+</Model>
--- /dev/null
+use strict;
+use warnings;
+use Test::More;
+
+
+use Catalyst::Test 'stemmaweb';
+use stemmaweb::Controller::Users;
+
+ok( request('/users')->is_success, 'Request should succeed' );
+done_testing();
--- /dev/null
+use strict;
+use warnings;
+use Test::More;
+
+
+BEGIN { use_ok 'stemmaweb::View::Email::Template' }
+
+done_testing();