Skip to content

Commit

Permalink
imported all the stuff we normally need in a project like this
Browse files Browse the repository at this point in the history
  • Loading branch information
norbu09 committed Mar 4, 2012
1 parent e07cdd3 commit f044edb
Show file tree
Hide file tree
Showing 73 changed files with 12,909 additions and 20 deletions.
11 changes: 11 additions & 0 deletions .gitignore
@@ -0,0 +1,11 @@
.*
!.gitignore
!.perltidyrc
*~
blib
Makefile*
!Makefile.PL
*META.*
MANIFEST*
!MANIFEST.SKIP
pm_to_blib
120 changes: 120 additions & 0 deletions Mojolicious/Plugin/CouchAuth.pm
@@ -0,0 +1,120 @@
package Mojolicious::Plugin::CouchAuth;

use Mojo::Base 'Mojolicious::Plugin';
use Store::CouchDB;
use Digest::SHA qw(sha256_base64);

sub register {
my ( $self, $app, $params ) = @_;

my $couch = Store::CouchDB->new(
port => $params->{port},
db => $params->{db},
debug => 1
);
my $password_reset_timeout = 172800; # two days

$app->helper(
auth => sub {
my ($self) = @_;

return 1 if $self->session->{user_id};
return unless $self->param('username');

my $doc = _get_user($couch, $self->param('username'));
return unless $doc;

if (sha256_base64( $self->param('password') ) eq $doc->{password}){
$self->session(name => $doc->{name});
$self->session(user_id => $doc->{_id});
$self->session(admin => 1) if (defined $doc->{role} && $doc->{role} eq 'admin');
$self->session(last_login => _set_last_login($couch, $doc));
return 1
}
},
);
$app->helper(
is_admin => sub {
my ($self) = @_;

my $doc = _get_user($couch, $self->param('username'));
return unless $doc;

return 1
if (defined $doc->{role} && $doc->{role} eq 'admin');
},
);
$app->helper(
update_password => sub {
my ($self) = @_;
my $doc = _get_user($couch, $self->param('username'));
return unless $doc;
$doc->{password} = sha256_base64( $self->param('password'));
return $couch->put_doc({doc => $doc});
},
);
$app->helper(
add_password_reset => sub {
my $self = shift;

my $user = _get_user($couch, $self->param('username'));
return unless $user;
my $doc = {
username => $self->param('username'),
type => 'password_reset',
user => $user,
ts => time,
};
my $id = $couch->put_doc({doc => $doc});
return {id => $id, user => $user};
},
);
$app->helper(
get_password_reset => sub {
my ($self, $id) = @_;
my $doc = $couch->get_doc({id => $id});
return unless $doc;
if($doc->{ts} + $password_reset_timeout > time){
return $doc;
} else {
$couch->del_doc({id => $id});
}
return;
},
);
$app->helper(
expire_password_reset => sub {
my ($self, $id) = @_;
return $couch->del_doc({id => $id});
},
);
$app->helper(
check_free => sub {
my ($self, $username) = @_;
return _get_user($couch, $username);
},
);
}

sub _get_user {
my ($couch, $username) = @_;

return $couch->get_doc({id => $username}) unless ($username =~ m/@/);

my $docs = $couch->get_view({
view => 'site/user',
opts => { key => $username, include_docs => 'true' },
});
return $docs->{ $username };
}

sub _set_last_login {
my ($couch, $doc) = @_;

my $last_login = $doc->{last_login};
$doc->{last_login} = time;
$couch->put_doc({doc => $doc});
return $last_login;
}

1;
80 changes: 80 additions & 0 deletions Mojolicious/Plugin/FormValidate.pm
@@ -0,0 +1,80 @@
package Mojolicious::Plugin::FormValidate;

use Mojo::Base 'Mojolicious::Plugin';
use Digest::SHA qw(sha256_base64);
use Data::Dumper;

sub register {
my ( $plugin, $app, $conf ) = @_;

$app->helper(
check_missing => sub {
my $self = shift;
my @mandatory = split( /,/, $self->param('mandatoryfields') );
my @err;
foreach my $ky (@mandatory) {
push(@err, $ky) unless $self->param($ky);
}
return \@err;
}
);

$app->helper(
process_form => sub {
#$app->log->debug(Dumper(@_));
my $self = shift;
my $page = shift || {};
my $back = shift || $self->req->url->to_string;
my @fields = split( /,/, $self->param('formfields') );
my @error;
foreach my $ky (@fields) {
next unless $self->param($ky);
if(check_field($ky, $self->param($ky))){
push(@error, $ky);
}
if ( $ky eq 'password' ) {
$page->{$ky} = sha256_base64( $self->param($ky) );
}
else {
$page->{$ky} = $self->param($ky);
}
}
my @msg;
my $missing = $self->check_missing();
if($missing->[0]){
push(@msg, "You are missing the following fields: " . join(', ', @{$missing}) );
} elsif (@error){
push(@msg, "The following fields were not validating: " . join(', ', @error));
}
if(@msg){
$self->flash(error => join('<br>', @msg));
$app->log->debug("Got errors, should not return anything!");
$self->flash(page => $page);
$self->redirect_to($back);
return;
} else {
return $page;
}
},

);

}

sub check_field {
my $field = shift;
my $string = shift;

my $definitions = {
username => '^[-\w\.]+@[-\w\.]+\.[-\w\.]+$',
password => '\w{3,128}',
description => '.{3,20000}',
};
# fall back to a rather generic test to cover all fields not defined
# explicitly.
my $def = $definitions->{$field} || '.{3,200}';
return 1 unless ($string =~ m{^$def$});
return;
}

1;

0 comments on commit f044edb

Please sign in to comment.