Skip to content

Commit

Permalink
Passwords are now OTPed instead of being stored in the clear in the
Browse files Browse the repository at this point in the history
user's session.
  • Loading branch information
mynnx committed Nov 15, 2010
1 parent 5ff736e commit afc8a99
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 25 deletions.
77 changes: 55 additions & 22 deletions lib/QuietReader.pm
@@ -1,8 +1,21 @@
package QuietReader;
use Dancer ':syntax';
use Data::Dumper;
use Dancer::Session;
use Dancer::Plugin::DBIC;

use WebService::Google::Reader;
use Data::Dumper;
use Data::Random qw(rand_chars);
use Crypt::OTP qw(OTP);

sub make_reader_otp {
my ($user, $otp_pass) = @_;
my $auth = schema->resultset('Auth')->find({ username => $user });

This comment has been minimized.

Copy link
@ironcamel

ironcamel Nov 15, 2010

Contributor

If username is the primary key, then you should write this as:
my $auth = schema->resultset('Auth')->find($user);

return undef if ! $auth;

my $pass = OTP($auth->otp, $otp_pass, 1);
return make_reader($user, $pass);
}

sub make_reader {
my ($user, $pass) = @_;
Expand All @@ -21,6 +34,13 @@ before sub {
}
};

# Gets a list of all feeds and the categories they belong
# to, and organizes them by category. Returns a hashref like:
# {
# 'blogs' => [{ title => 'a blog', href => 'http://...'}, ...] }
# }
#
# Feeds not under any category are put in the 'none' key.
sub build_feeds {
my $reader = shift;
my $categories = { none => [] };
Expand All @@ -47,51 +67,64 @@ sub build_feeds {
}

sub render_tags {
my $reader = make_reader(session('user'), session('pass'));
my $error = $reader->error ? "error: " . $reader->error : "";
my $tagged = build_feeds($reader);
my $untagged = delete $tagged->{'none'} || ();
debug Dumper $untagged;
template tags => {
tagged => $tagged,
untagged => $untagged,
error => $error
};
my $reader = make_reader_otp(session('user'), session('otp_pass'));

if (! $reader || $reader->error) {
my $error = "error: ";
if ($reader) {
$error .= $reader->error;
} else {
$error = "Could not retrieve OTP from database";
}
session error => $error;
redirect '/login';
} else {
my $tagged = build_feeds($reader);
my $untagged = delete $tagged->{'none'} || [];
template tags => {
tagged => $tagged,
untagged => $untagged,
};
}
};

get '/' => \&render_tags;
get '/tags' => \&render_tags;

get '/login' => sub {
my $path_requested = vars->{requested_path} || '/';
my $failed = params->{failed};
template login => {
path_requested => $path_requested,
login_failed => $failed ? "Login failed" : "",
error => session('error')
};
};

post '/login' => sub {
my $user = params->{username};
my $pass = params->{password};
my $rv = "";
my $reader = make_reader($user, $pass);

# Call ->tags, which may actually cause an ->error; creating a new
# ::Reader doesn't actually hit the API, I don't think.
my @tags = $reader->tags;
if ($reader->error) {
redirect '/login?failed=1';
session error => 'Login failed. Check your credentials, bro.';
redirect '/login';
} else {
session user => $user,
session pass => $pass,
# TODO generate/store OTP, encrypt password with it and put in cookie
# - clear your session persistent store; passwords are plaintext for now!
# OTP generation uses Crypt::Random, which isn't recommended -
# find a different way to make a OTP if you're paranoid.
my $otp = join('', rand_chars(set => 'all', size => length $pass));
my $otp_pass = OTP($otp, $pass, 1);
session user => $user;
session otp_pass => $otp_pass;

my $auth = schema->resultset('Auth')->update_or_create({
username => $user,
otp => $otp
});

redirect params->{path} || '/';
}
return $rv;
};



true;
2 changes: 1 addition & 1 deletion views/login.tt
@@ -1,7 +1,7 @@

<form action="/login" method="POST">
<input type="text" name="username" /><br>
<input type="password" name="password" /><br>
<input type="hidden" name="path" value="[% path_reequested %]" />
<input type="submit" value="Log in" />
</form>
<font color="red">[% error %]</font>
5 changes: 3 additions & 2 deletions views/tags.tt
@@ -1,6 +1,8 @@

<form action="/tags" method="POST">
Unsorted:<br />
[% IF untagged.size > 0 %]
Unsorted:<br />
[% END %]
[% FOREACH feed in untagged %]
<input type="checkbox" name="[% feed.href %]">
<a href="[% feed.href %]">[% feed.title %]</a><br />
Expand All @@ -14,4 +16,3 @@
[% END %]
[% END %]
</form>
[% error %]

0 comments on commit afc8a99

Please sign in to comment.