From d5bc5cf2169116a9a4b30377ef2e28603fc4e3ea Mon Sep 17 00:00:00 2001 From: Yorhel Date: Fri, 31 Oct 2008 12:04:08 +0100 Subject: Added some authentication and user functions --- data/global.pl | 10 ++++++ lib/VNDB/DB/Misc.pm | 1 + lib/VNDB/DB/Users.pm | 44 +++++++++++++++++++++++ lib/VNDB/Util/Auth.pm | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++ util/vndb.pl | 8 ++++- yawf | 2 +- 6 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 lib/VNDB/DB/Users.pm create mode 100644 lib/VNDB/Util/Auth.pm diff --git a/data/global.pl b/data/global.pl index f566f2b4..0c520717 100644 --- a/data/global.pl +++ b/data/global.pl @@ -17,6 +17,16 @@ our %S = ( version => 'beta', url => 'http://vndb.org', url_static => 'http://s.vndb.org', + cookie_domain => '.vndb.org', + cookie_key => 'any-private-string-here', + user_ranks => [ + # rankname allowed actions # DB number + [qw| visitor hist |], # 0 + [qw| loser hist |], # 1 + [qw| user hist board edit |], # 2 + [qw| mod hist board boardmod edit mod lock del |], # 3 + [qw| admin hist board boardmod edit mod lock del usermod |], # 4 + ], ); diff --git a/lib/VNDB/DB/Misc.pm b/lib/VNDB/DB/Misc.pm index 50a12a4b..61b1223c 100644 --- a/lib/VNDB/DB/Misc.pm +++ b/lib/VNDB/DB/Misc.pm @@ -13,6 +13,7 @@ our @EXPORT = qw| # Arguments: array of elements to get stats from, options: # vn, producers, releases, users, threads, posts # Returns: hashref, key = element, value = number of entries +# TODO: caching, see http://www.varlena.com/GeneralBits/120.php sub dbStats { my $s = shift; return { map { diff --git a/lib/VNDB/DB/Users.pm b/lib/VNDB/DB/Users.pm new file mode 100644 index 00000000..9e83ea2b --- /dev/null +++ b/lib/VNDB/DB/Users.pm @@ -0,0 +1,44 @@ + +package VNDB::DB::Users; + +use Exporter 'import'; + +our @EXPORT = 'dbUserGet'; + + +# %options->{ username passwd order uid results page } +sub dbUserGet { + my $s = shift; + my %o = ( + order => 'username ASC', + page => 1, + results => 10, + what => '', + @_ + ); + + my %where = ( + $o{username} ? ( + 'username = ?' => $o{username} ) : (), + $o{passwd} ? ( + 'passwd = decode(?, \'hex\')' => $o{passwd} ) : (), + $o{uid} ? ( + 'id = ?' => $o{uid} ) : (), + !$o{uid} && !$o{username} ? ( + 'id > 0' => 1 ) : (), + ); + + my($r, $np) = $s->dbPage(\%o, q| + SELECT * + FROM users u + !W + ORDER BY !s|, + \%where, + $o{order} + ); + + return wantarray ? ($r, $np) : $r; +} + + +1; diff --git a/lib/VNDB/Util/Auth.pm b/lib/VNDB/Util/Auth.pm new file mode 100644 index 00000000..5ac9218f --- /dev/null +++ b/lib/VNDB/Util/Auth.pm @@ -0,0 +1,96 @@ + +package VNDB::Util::Auth; + +# This module is just a small improvement of the 1.x equivalent +# and is designed to work with the cookies and database of VNDB 1.x +# without modifications. A proper and more secure (incompatible) +# implementation should be written at some point. + +use strict; +use warnings; +use Exporter 'import'; +use Digest::MD5 'md5_hex'; +use Crypt::Lite; + + +our @EXPORT = qw| authInit authLogin authLogout authInfo authCan |; + + +# initializes authentication information and checks the vndb_auth cookie +sub authInit { + my $self = shift; + $self->{_auth} = undef; + + my $cookie = $self->reqCookie('vndb_auth'); + return 0 if !$cookie; + my $str = Crypt::Lite->new()->decrypt($cookie, md5_hex($self->{cookie_key})); + return 0 if length($str) < 36; + my $pass = substr($str, 4, 32); + my $user = substr($str, 36); + _authCheck($self, $user, $pass); +} + + +# login, arguments: user, password, url-to-redirect-to-on-success +# returns 1 on success (redirected), 0 otherwise (no reply sent) +sub authLogin { + my $self = shift; + my $user = lc(scalar shift); + my $pass = md5_hex(shift); + my $to = shift; + + if(_authCheck($self, $user, $pass)) { + (my $cookie = Crypt::Lite->new()->encrypt("VNDB$pass$user", md5_hex($self->{cookie_key}))) =~ s/\r?\n//g; + $self->resRedirect($to, 'post'); + $self->resHeader('Set-Cookie', "vndb_auth=$cookie; expires=Sat, 01-Jan-2030 00:00:00 GMT; path=/; domain=$self->{cookie_domain}"); + return 1; + } + return 0; +} + + +# clears authentication cookie and redirects to / +sub authLogout { + my $self = shift; + $self->resRedirect('/', 'temp'); + $self->resAddHeader('Set-Cookie', "vndb_auth= ; expires=Sat, 01-Jan-2000 00:00:00 GMT; path=/; domain=$self->{cookie_domain}"); +} + + +# returns a hashref with information about the current loggedin user +# the hash is identical to the hash returned by dbUserGet +# returns empty hash if no user is logged in. +sub authInfo { + return shift->{_auth} || {}; +} + + +# returns whether the currently loggedin or anonymous user can perform +# a certain action. Argument is the action name as defined in global.pl +sub authCan { + my($self, $act) = @_; + my $r = $self->{_auth}{rank}||0; + return scalar grep $_ eq $act, @{$self->{user_ranks}[$r]}[1..$#{$self->{user_ranks}[$r]}]; +} + + +# Checks for a valid login and writes information in _auth +# Arguments: user, md5_hex(pass) +# Returns: 1 if login is valid, 0 otherwise +sub _authCheck { + my($self, $user, $pass) = @_; + + return 0 if + !$user || length($user) > 15 || length($user) < 2 + || !$pass || length($pass) != 32; + + my $d = $self->dbUserGet(username => $user, passwd => $pass)->[0]; + return 0 if !defined $d->{id} || !$d->{rank}; + + $self->{_auth} = $d; + return 1; +} + + +1; + diff --git a/util/vndb.pl b/util/vndb.pl index a076dcc8..c1810148 100755 --- a/util/vndb.pl +++ b/util/vndb.pl @@ -29,7 +29,13 @@ require $ROOT.'/data/global.pl'; YAWF::init( %O, namespace => 'VNDB', - object_data => \%S + object_data => \%S, + pre_request_handler => \&reqinit, ); +sub reqinit { + my $self = shift; + $self->authInit; +} + diff --git a/yawf b/yawf index 3499c666..38ea3a71 160000 --- a/yawf +++ b/yawf @@ -1 +1 @@ -Subproject commit 3499c666034942a162ed6d93726e43ff74f57ee6 +Subproject commit 38ea3a713af1aa9f51986e643055c2b5bca2d9d9 -- cgit v1.2.3