From: Michael Andreen Date: Tue, 17 Jun 2008 22:25:09 +0000 (+0200) Subject: Login/Logout and session support with roles + convert to html 4.01. X-Git-Url: https://ruin.nu/git/?p=ndwebbie.git;a=commitdiff_plain;h=49c23244b1ba61909b726bb9189665a33027a1af Login/Logout and session support with roles + convert to html 4.01. Roles give a fine-grained access control. Roles can be shared by different groups, so there is no need to check for more than one role in most cases. --- diff --git a/ND.pm b/ND.pm deleted file mode 100755 index e9bc401..0000000 --- a/ND.pm +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/perl -w -T -#************************************************************************** -# Copyright (C) 2006 by Michael Andreen * -# * -# This program is free software; you can redistribute it and/or modify * -# it under the terms of the GNU General Public License as published by * -# the Free Software Foundation; either version 2 of the License, or * -# (at your option) any later version. * -# * -# This program is distributed in the hope that it will be useful, * -# but WITHOUT ANY WARRANTY; without even the implied warranty of * -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# GNU General Public License for more details. * -# * -# You should have received a copy of the GNU General Public License * -# along with this program; if not, write to the * -# Free Software Foundation, Inc., * -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * -#**************************************************************************/ - -package ND; -use CGI qw/:standard/; -use DBI; -use DBD::Pg qw(:pg_types); -use Apache2::Request; -use Apache2::Response; -use Apache2::RequestUtil; -use ND::DB; -use NDWeb::Page; -use strict; -use warnings; - -$SIG{__WARN__} = sub {$ND::ERROR .= p $_[0]}; - -chdir '/var/www/ndawn'; - -sub handler { - my $r = shift; - my $req = Apache2::Request->new($r, POST_MAX => "1M"); - local $ND::DBH = ND::DB::DB(); - local $ND::UID; - local $ND::ERROR; - my $page = $req->param('page'); - $r->no_cache; - - if ($ENV{'SCRIPT_NAME'} =~ /(\w+)(\.(pl|php|pm))?$/){ - $page = $1 unless $1 eq 'index' and $3 eq 'pl'; - } - $page = NDWeb::Page->new(PAGE => $page, DBH => $ND::DBH, URI => $ENV{REQUEST_URI}, USER_AGENT => $ENV{HTTP_USER_AGENT}, HTTP_ACCEPT => $ENV{HTTP_ACCEPT}, R => $r); - $page->render; - - $ND::DBH->rollback unless $ND::DBH->{AutoCommit}; - $ND::DBH->disconnect; - - if ($page->{RETURN}){ - if($page->{RETURN} eq 'REDIRECT'){ - $r->headers_out->set(Location => $page->{REDIR_LOCATION}); - $r->status(Apache2::Const::REDIRECT); - $r->rflush; - } - } - return Apache2::Const::OK; -} - -1; diff --git a/NDWeb/AuthHandler.pm b/NDWeb/AuthHandler.pm deleted file mode 100644 index 086d46b..0000000 --- a/NDWeb/AuthHandler.pm +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/perl -w -T -#************************************************************************** -# Copyright (C) 2006 by Michael Andreen * -# * -# This program is free software; you can redistribute it and/or modify * -# it under the terms of the GNU General Public License as published by * -# the Free Software Foundation; either version 2 of the License, or * -# (at your option) any later version. * -# * -# This program is distributed in the hope that it will be useful, * -# but WITHOUT ANY WARRANTY; without even the implied warranty of * -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# GNU General Public License for more details. * -# * -# You should have received a copy of the GNU General Public License * -# along with this program; if not, write to the * -# Free Software Foundation, Inc., * -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * -#**************************************************************************/ - -package NDWeb::AuthHandler; -use strict; -use warnings FATAL => 'all'; - -use ND::DB; -use Apache2::Access (); - -sub handler { - my $r = shift; - my($res, $sent_pw) = $r->get_basic_auth_pw; - return $res if $res != Apache2::Const::OK; - - my $dbh = ND::DB::DB(); - my ($username) = $dbh->selectrow_array(q{SELECT username FROM users WHERE - lower(username) = lower(?) AND password = MD5(?)},undef,$r->user,$sent_pw); - $dbh->disconnect; - if ($username){ - $r->user($username); - return Apache2::Const::OK; - } - $r->note_basic_auth_failure(); - return Apache2::Const::AUTH_REQUIRED; -} - -1; diff --git a/NDWeb/Include.pm b/NDWeb/Include.pm deleted file mode 100644 index 5794b46..0000000 --- a/NDWeb/Include.pm +++ /dev/null @@ -1,91 +0,0 @@ -#************************************************************************** -# Copyright (C) 2006 by Michael Andreen * -# * -# This program is free software; you can redistribute it and/or modify * -# it under the terms of the GNU General Public License as published by * -# the Free Software Foundation; either version 2 of the License, or * -# (at your option) any later version. * -# * -# This program is distributed in the hope that it will be useful, * -# but WITHOUT ANY WARRANTY; without even the implied warranty of * -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# GNU General Public License for more details. * -# * -# You should have received a copy of the GNU General Public License * -# along with this program; if not, write to the * -# Free Software Foundation, Inc., * -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * -#**************************************************************************/ - -package NDWeb::Include; -use strict; -use warnings; -use CGI qw{:standard}; -require Exporter; -use BBCode::Parser; - -our @ISA = qw/Exporter/; - -our @EXPORT = qw/parseMarkup min max - alliances intelquery /; - -sub parseMarkup ($) { - my ($text) = @_; - - #$text =~ s{\n}{\n
}g; - #$text =~ s{\[B\](.*?)\[/B\]}{$1}gi; - #$text =~ s{\[I\](.*?)\[/I\]}{$1}gi; - #$text =~ s{\[url\](.*?)\[/url\]}{$1}gi; - #$text =~ s{\[PRE\](.*?)\[/PRE\]}{
$1
}sgi; - #$text =~ s{\[PRE\](.*?)\[/PRE\]}{
$1
}sgi; - #$1 =~ s{
}{}g; - - eval{ - my $tree = BBCode::Parser->DEFAULT->parse($text); - $text = $tree->toHTML; - }; - $text =~ s/\x{3}\d\d?//g; #mirc color TODO: possibly match until \x{0F} and change to [color] block - $text =~ s/[^\x{9}\x{A}\x{D}\x{20}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]//g; - return $text; -} - - -sub min { - my ($x,$y) = @_; - return ($x > $y ? $y : $x); -} - -sub max { - my ($x,$y) = @_; - return ($x < $y ? $y : $x); -} - - -sub alliances { - my ($alliance) = @_; - my @alliances; - $alliance = -1 unless defined $alliance; - push @alliances,{Id => -1, Name => '', Selected => not $alliance}; - my $query = $ND::DBH->prepare(q{SELECT id,name FROM alliances ORDER BY LOWER(name)}); - $query->execute; - while (my $ally = $query->fetchrow_hashref){ - push @alliances,{Id => $ally->{id}, Name => $ally->{name}, Selected => $alliance == $ally->{id}}; - } - return @alliances; -} - -sub intelquery { - my ($columns,$where) = @_; - return qq{ -SELECT $columns, i.mission, i.tick AS landingtick,MIN(i.eta) AS eta, i.amount, i.ingal, u.username -FROM (fleets i NATURAL JOIN users u) - JOIN current_planet_stats t ON i.target = t.id - JOIN current_planet_stats o ON i.sender = o.id -WHERE $where -GROUP BY i.tick,i.mission,t.x,t.y,t.z,o.x,o.y,o.z,i.amount,i.ingal,u.username,t.alliance,o.alliance,t.nick,o.nick -ORDER BY i.tick DESC, i.mission}; -} - - - -1; diff --git a/NDWeb/Page.pm b/NDWeb/Page.pm deleted file mode 100644 index e5e703d..0000000 --- a/NDWeb/Page.pm +++ /dev/null @@ -1,119 +0,0 @@ -#************************************************************************** -# Copyright (C) 2006 by Michael Andreen * -# * -# This program is free software; you can redistribute it and/or modify * -# it under the terms of the GNU General Public License as published by * -# the Free Software Foundation; either version 2 of the License, or * -# (at your option) any later version. * -# * -# This program is distributed in the hope that it will be useful, * -# but WITHOUT ANY WARRANTY; without even the implied warranty of * -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# GNU General Public License for more details. * -# * -# You should have received a copy of the GNU General Public License * -# along with this program; if not, write to the * -# Free Software Foundation, Inc., * -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * -#**************************************************************************/ -package NDWeb::Page; -use strict; -use warnings; -use CGI qw/:standard/; - -our %PAGES; - -sub new { - my $invocant = shift; - my $class = ref($invocant) || $invocant; - my $self = {@_}; - $self->{PAGE} = 'main' unless (defined $self->{PAGE} and exists $PAGES{$self->{PAGE}}); - $class = $PAGES{$self->{PAGE}}; - bless $self, $class; - $self->parse; - $self->initiate; - return $self; -} - -sub initiate : method { - my $self = shift; - my $DBH = $self->{DBH}; - - $DBH->do(q{SET timezone = 'GMT'}); - - ($self->{UID},$self->{PLANET},$self->{USER}) = $DBH->selectrow_array('SELECT uid,planet,username FROM users WHERE username ILIKE ?' - ,undef,$ENV{'REMOTE_USER'}); - $ND::UID = $self->{UID}; - - ($self->{TICK}) = $DBH->selectrow_array('SELECT tick()',undef); - $self->{TICK} = 0 unless defined $self->{TICK}; - - - my $query = $DBH->prepare('SELECT groupname,attack,gid from groupmembers NATURAL JOIN groups WHERE uid = ?'); - $query->execute($self->{UID}); - - while (my ($name,$attack,$gid) = $query->fetchrow()){ - $self->{GROUPS}{$name} = $gid; - $self->{ATTACKER} = 1 if $attack; - } - - -} - -sub parse : method { -} - -sub render_body : method { - return ""; -} - -sub render : method { - my $self = shift; - - print header; - print $self->render_body; -} - -sub isInGroup ($) : method { - my $self = shift; - my $group = shift; - return exists $self->{GROUPS}{$group} || exists $self->{GROUPS}{Tech} || exists $self->{GROUPS}{HC}; -} - -sub isMember () : method { - my $self = shift; - $self->isInGroup('Members'); -} - -sub isHC () : method { - my $self = shift; - $self->isInGroup('HC'); -} - -sub isDC () : method { - $_[0]->isInGroup('DC'); -} - -sub isBC () : method { - $_[0]->isInGroup('BC'); -} - -sub isOfficer () : method { - $_[0]->isInGroup('Officers'); -} - -sub isScanner () : method { - $_[0]->isInGroup('Scanners'); -} - -sub isIntel () : method { - $_[0]->isInGroup('Intel'); -} - -sub isTech () : method { - $_[0]->isInGroup('Tech'); -} - - - -1; diff --git a/NDWeb/XMLPage.pm b/NDWeb/XMLPage.pm deleted file mode 100644 index 288bfb2..0000000 --- a/NDWeb/XMLPage.pm +++ /dev/null @@ -1,141 +0,0 @@ -#************************************************************************** -# Copyright (C) 2006 by Michael Andreen * -# * -# This program is free software; you can redistribute it and/or modify * -# it under the terms of the GNU General Public License as published by * -# the Free Software Foundation; either version 2 of the License, or * -# (at your option) any later version. * -# * -# This program is distributed in the hope that it will be useful, * -# but WITHOUT ANY WARRANTY; without even the implied warranty of * -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# GNU General Public License for more details. * -# * -# You should have received a copy of the GNU General Public License * -# along with this program; if not, write to the * -# Free Software Foundation, Inc., * -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * -#**************************************************************************/ - -package NDWeb::XMLPage; -use strict; -use warnings; -use CGI qw/:standard/; -use HTML::Template; - -use ND::Include; -use NDWeb::Page; -use NDWeb::Include; - -use base qw/NDWeb::Page/; - -sub noAccess () { - HTML::Template->new(filename => 'templates/NoAccess.tmpl', global_vars => 1, cache => 1); -}; - -sub process : method { -} - -sub listTargets () : method { - my $self = shift; - my $DBH = $self->{DBH}; - my $query = $DBH->prepare(qq{SELECT t.id, r.id AS raid, r.tick+c.wave-1 AS landingtick, - (released_coords AND old_claim(timestamp)) AS released_coords, coords(x,y,z),c.launched,c.wave,c.joinable -FROM raid_claims c - JOIN raid_targets t ON c.target = t.id - JOIN raids r ON t.raid = r.id - JOIN current_planet_stats p ON t.planet = p.id -WHERE c.uid = ? AND r.tick+c.wave > ? AND r.open AND not r.removed -ORDER BY r.tick+c.wave,x,y,z}); - $query->execute($ND::UID,$self->{TICK}); - my @targets; - while (my $target = $query->fetchrow_hashref){ - my $coords = "Target $target->{id}"; - $coords = $target->{coords} if $target->{released_coords}; - push @targets,{Coords => $coords, Launched => $target->{launched}, Raid => $target->{raid} - , Target => $target->{id}, Tick => $target->{landingtick}, Wave => $target->{wave} - , AJAX => $self->{AJAX}, JoinName => $target->{joinable} ? 'N' : 'J' - , Joinable => $target->{joinable} ? 'FALSE' : 'TRUE', JoinableTitle => $target->{joinable} ? 'Disable join' : 'Make target joinable'}; - } - my $template = HTML::Template->new(filename => "templates/targetlist.tmpl", cache => 1); - $template->param(Targets => \@targets); - return $template->output; -} - - -sub render : method { - my $self = shift; - my $DBH = $self->{DBH}; - - - chdir '/var/www/ndawn/code'; - - my $template = HTML::Template->new(filename => 'templates/skel.tmpl', global_vars => 1, cache => 1); - - my $TICK = $self->{TICK}; - my $ATTACKER = $self->{ATTACKER}; - - $self->{XML} = 0; - $self->{AJAX} = 1; - - $self->process; - - my $type = 'text/html'; - if ($self->{HTTP_ACCEPT} =~ m{application/xhtml\+xml}){ - $type = 'application/xhtml+xml' - } - my $body; - if ($self->{XML}){ - $type = 'text/xml'; - $template = HTML::Template->new(filename => "templates/xml.tmpl", cache => 1); - $body = HTML::Template->new(filename => "templates/$self->{PAGE}.xml.tmpl", cache => 1); - }else{ - $body = HTML::Template->new(filename => "templates/$self->{PAGE}.tmpl", global_vars => 1 - , cache => 1, loop_context_vars => 1, default_escape => 'HTML'); - $body->param(PAGE => $self->{PAGE}); - } - - $body = $self->render_body($body); - - unless ($body){ - return; - } - - unless ($self->{XML}){ - #TODO: Need to fix this with new stuff. - my $fleetupdate = $DBH->selectrow_array(q{SELECT tick FROM fleets WHERE sender = ? AND mission = 'Full fleet' AND tick > tick() - 24},undef,$self->{PLANET}); - - $fleetupdate = 0 unless defined $fleetupdate; - - my ($last_forum_visit) = $DBH->selectrow_array(q{SELECT last_forum_visit FROM users WHERE uid = $1} - ,undef,$self->{UID}) or $ND::ERROR .= p($DBH->errstr); - my ($unread,$newposts) = $DBH->selectrow_array(unread_query(),undef,$self->{UID},$last_forum_visit) - or $ND::ERROR .= p($DBH->errstr); - - $template->param(UnreadPosts => $unread); - $template->param(NewPosts => $newposts); - $template->param(Tick => $TICK); - $template->param(isMember => $self->isMember); - $template->param(Planet => $self->{PLANET}); - $template->param(isHC => $self->isHC); - $template->param(isDC => $self->isDC()); - $template->param(isBC => $self->isBC()); - $template->param(isIntel => $self->isIntel()); - $template->param(isAttacker => $ATTACKER && (!$self->isMember() || ((($TICK - $fleetupdate < 24) || $self->isScanner()) && $self->{PLANET}))); - if ($ATTACKER && (!$self->isMember() || ((($TICK - $fleetupdate < 24) || $self->isScanner()) && $self->{PLANET}))){ - $template->param(Targets => $self->listTargets); - } - $template->param(Coords => param('coords') ? param('coords') : '1:1:1'); - my ($css) = $DBH->selectrow_array(q{SELECT css FROM users WHERE uid = $1},undef,$ND::UID); - $template->param(CSS => $css); - $template->param(TITLE => $self->{TITLE}); - } - $template->param(Error => $ND::ERROR); - $template->param(BODY => $body->output); - my $output = $template->output; - $output =~ s/[^\x{9}\x{A}\x{D}\x{20}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]//g; - print header(-type=> $type, -charset => 'utf-8', -Content_Length => length $output); - print $output; -}; - -1; diff --git a/database/group_roles.sql b/database/group_roles.sql new file mode 100644 index 0000000..e890bb5 --- /dev/null +++ b/database/group_roles.sql @@ -0,0 +1,33 @@ +CREATE TABLE roles ( + role VARCHAR(20) UNIQUE NOT NULL +); + +CREATE TABLE group_roles ( + gid INTEGER REFERENCES groups(gid), + role VARCHAR(20) REFERENCES roles(role) +); + +INSERT INTO roles VALUES('member_menu'); +INSERT INTO roles VALUES('hc_menu'); +INSERT INTO roles VALUES('bc_menu'); +INSERT INTO roles VALUES('dc_menu'); +INSERT INTO roles VALUES('intel_menu'); +INSERT INTO roles VALUES('attack_menu'); +INSERT INTO roles VALUES('no_fleet_update'); + +INSERT INTO group_roles (gid,role) VALUES(2,'member_menu'); +INSERT INTO group_roles (gid,role) VALUES(2,'attack_menu'); +INSERT INTO group_roles (gid,role) VALUES(6,'dc_menu'); +INSERT INTO group_roles (gid,role) VALUES(4,'bc_menu'); +INSERT INTO group_roles (gid,role) VALUES(5,'intel_menu'); +INSERT INTO group_roles (gid,role) VALUES(8,'no_fleet_update'); + +INSERT INTO group_roles (gid,role) VALUES(1,'dc_menu'); +INSERT INTO group_roles (gid,role) VALUES(1,'bc_menu'); +INSERT INTO group_roles (gid,role) VALUES(1,'hc_menu'); +INSERT INTO group_roles (gid,role) VALUES(1,'intel_menu'); + +INSERT INTO group_roles (gid,role) VALUES(3,'dc_menu'); +INSERT INTO group_roles (gid,role) VALUES(3,'bc_menu'); +INSERT INTO group_roles (gid,role) VALUES(3,'hc_menu'); +INSERT INTO group_roles (gid,role) VALUES(3,'intel_menu'); diff --git a/lib/Catalyst/Plugin/Authentication/Store/NDWeb.pm b/lib/Catalyst/Plugin/Authentication/Store/NDWeb.pm new file mode 100644 index 0000000..ff90aff --- /dev/null +++ b/lib/Catalyst/Plugin/Authentication/Store/NDWeb.pm @@ -0,0 +1,77 @@ +package Catalyst::Plugin::Authentication::Store::NDWeb; + +use strict; +use warnings; +use base qw/Class::Accessor::Fast/; + +use NDWeb::Auth::User; + +our $VERSION= "0.104"; + + +BEGIN { + #__PACKAGE__->mk_accessors(qw/config/); +} + + +sub setup { + my $c = shift; + + $c->default_auth_store( + Catalyst::Plugin::Authentication::Store::NDWeb->new( + ) + ); + + $c->NEXT::setup(@_); + +} + +sub new { + my ( $class ) = @_; + + my $self = { + }; + + bless $self, $class; +} + +sub from_session { + my ( $self, $c, $frozenuser ) = @_; + + my $user = NDWeb::Auth::User->new(); + + return $user->from_session($frozenuser, $c); +} + +sub for_session { + my ($self, $c, $user) = @_; + return $user->for_session($c); +} + +sub find_user { + my ( $self, $authinfo, $c ) = @_; + + my $user = NDWeb::Auth::User->new();; + + return $user->load($authinfo, $c); +} + +sub user_supports { + my $self = shift; + # this can work as a class method on the user class + NDWeb::User->supports( @_ ); +} + +__PACKAGE__; + +__END__ + +=head1 AUTHOR + +Michael Andreen (harv@ruin.nu) + +=head1 LICENSE + +GPL 2.0, or later. + +=cut diff --git a/lib/ND b/lib/ND index 193d9ed..245cb3b 160000 --- a/lib/ND +++ b/lib/ND @@ -1 +1 @@ -Subproject commit 193d9ed10fea0563da8da5f54ec42f3068547dd4 +Subproject commit 245cb3b058157d719b02be466e1b4deaa72fc986 diff --git a/lib/NDWeb.pm b/lib/NDWeb.pm index 2dbab22..85bbf83 100644 --- a/lib/NDWeb.pm +++ b/lib/NDWeb.pm @@ -27,10 +27,27 @@ our $VERSION = '0.01'; # local deployment. __PACKAGE__->config( name => 'NDWeb' ); +__PACKAGE__->config->{'Plugin::Authentication'}{'use_session'} = 1; + -# Start the application -__PACKAGE__->setup(qw/-Debug ConfigLoader Static::Simple/); +# Start the application +__PACKAGE__->setup(qw/ + -Debug + ConfigLoader + Static::Simple + + Authentication + Authentication::Store::NDWeb + Authentication::Credential::Password + + Authorization::Roles + Authorization::ACL + + Session + Session::Store::File + Session::State::Cookie + /); =head1 NAME diff --git a/lib/NDWeb/Auth/User.pm b/lib/NDWeb/Auth/User.pm new file mode 100644 index 0000000..490f188 --- /dev/null +++ b/lib/NDWeb/Auth/User.pm @@ -0,0 +1,127 @@ +package NDWeb::Auth::User; + +use strict; +use warnings; +use Data::Dumper; +use base qw/Catalyst::Authentication::User/; +use base qw/Class::Accessor::Fast/; + +BEGIN { + __PACKAGE__->mk_accessors(qw//); + __PACKAGE__->mk_ro_accessors(qw/username id css planet _roles/); +}; + +sub new { + my ( $class ) = @_; + my $self = { + _roles => undef, + username => undef, + id => undef, + c => undef, + }; + bless $self, $class; + return $self; +} + + + +sub load { + my ($self, $authinfo, $c) = @_; + $self->{c} = $c; + my $dbh = $c->model; + + if (exists $authinfo->{id}){ + $self->{id} = $dbh->selectrow_array(q{ + SELECT uid FROM users WHERE lower(username) = lower(?) + },undef,$authinfo->{id}); + }elsif (exists $authinfo->{uid}){ + $self->{id} = $authinfo->{uid}; + } + unless($self->{id}){ + $c->logout; + return $self + } + + ($self->{planet},$self->{username},$self->{css}) = $dbh->selectrow_array(q{ + SELECT planet,username,css FROM users WHERE uid = ? + },undef,$self->{id}) or die $dbh->errstr; + + return $self; +} + +sub supported_features { + my $self = shift; + + return { + password => { + self_check => 1, + }, + session => 1, + roles => 1, + }; +} + + +sub roles { + my ( $self ) = shift; + + ## shortcut if we have already retrieved them + if (ref $self->_roles eq 'ARRAY') { + return(@{$self->_roles}); + } + my $dbh = $self->{c}->model; + + my $query = $dbh->prepare(q{SELECT role FROM group_roles + WHERE gid IN (SELECT gid FROM groupmembers WHERE uid = $1) + }) or die $dbh->errstr; + + my @roles = (); + $query->execute($self->id); + while (my $group = $query->fetchrow_hashref){ + push @roles,$group->{role}; + } + $self->{_roles} = \@roles; + + return @{$self->_roles}; +} + +sub for_session { + my $self = shift; + + my $userdata = { + uid => $self->id + }; + return $userdata; +} + +sub from_session { + my ($self, $frozenuser, $c) = @_; + + return $self->load($frozenuser, $c); +} + +sub check_password { + my ( $self, $password ) = @_; + my $query = $self->{c}->model->prepare(q{ + SELECT uid FROM users WHERE uid = ? AND password = md5(?) + }); + $query->execute($self->id,$password); + if ($query->rows == 1){ + return $self; + } + return; +} + + +1; +__END__ + +=head1 AUTHOR + +Michael Andreen (harv@ruin.nu) + +=head1 LICENSE + +GPL 2, or later. + +=cut diff --git a/lib/NDWeb/Controller/Root.pm b/lib/NDWeb/Controller/Root.pm index 0a41059..6685c85 100644 --- a/lib/NDWeb/Controller/Root.pm +++ b/lib/NDWeb/Controller/Root.pm @@ -4,6 +4,8 @@ use strict; use warnings; use parent 'Catalyst::Controller'; +use ND::Include; + # # Sets the actions in this controller to be registered with no prefix # so they function identically to actions created in MyApp.pm @@ -27,25 +29,84 @@ NDWeb::Controller::Root - Root Controller for NDWeb =cut sub index : Local Path Args(0) { - my ( $self, $c ) = @_; - - $c->stash(abc => $c->req->base); + my ( $self, $c ) = @_; } sub default : Path { - my ( $self, $c ) = @_; + my ( $self, $c ) = @_; $c->res->body( 'Page not found' ); - $c->response->status(404); - + $c->response->status(404); } -sub auto : Private { +sub login : Local { + my ($self, $c) = @_; + if ($c->login){ + $c->res->redirect($c->uri_for('index')); + return; + } + + $c->stash(error => 'Bad password'); + $c->stash(template => 'index.tt2'); + $c->forward('index'); +} + +sub logout : Local { + my ($self, $c) = @_; + $c->logout; + $c->res->redirect($c->uri_for('index')); +} + +#sub begin : private { +#} + +sub listTargets : Private { my ($self, $c) = @_; my $dbh = $c ->model; + + my $query = $dbh->prepare(q{SELECT t.id, r.id AS raid, r.tick+c.wave-1 AS landingtick, + (released_coords AND old_claim(timestamp)) AS released_coords, coords(x,y,z),c.launched,c.wave,c.joinable +FROM raid_claims c + JOIN raid_targets t ON c.target = t.id + JOIN raids r ON t.raid = r.id + JOIN current_planet_stats p ON t.planet = p.id +WHERE c.uid = $1 AND r.tick+c.wave > tick() AND r.open AND not r.removed +ORDER BY r.tick+c.wave,x,y,z}); + $query->execute($c->user->id) or die $dbh->errstr; + my @targets; + while (my $target = $query->fetchrow_hashref){ + push @targets, $target; + } + + $c->stash(targets => \@targets); +} + +sub auto : Private { + my ($self, $c) = @_; + my $dbh = $c ->model; + $c->stash(dbh => $dbh); - $c->stash->{game}->{tick} = $dbh->selectrow_array('SELECT tick()',undef); + $dbh->do(q{SET timezone = 'GMT'}); + + $c->stash(TICK =>$dbh->selectrow_array('SELECT tick()',undef)); + $c->stash->{game}->{tick} = $c->stash->{TICK}; + + if ($c->user_exists){ + $c->stash(UID => $c->user->id); + }else{ + $c->stash(UID => -4); + } + +} + +sub access_denied : Private { + my ($self, $c, $action) = @_; + + $c->log->debug('moo' . $action); + + # Set the error message + $c->stash->{template} = 'access_denied.tt2'; } @@ -55,16 +116,44 @@ Attempt to render a view, if needed. =cut -sub end : ActionClass('RenderView') {} +sub end : ActionClass('RenderView') { + my ($self, $c) = @_; + + my $dbh = $c ->model; + + if ($c->user_exists && $c->res->status == 200){ + my $fleetupdate = 0; + if ($c->check_user_roles(qw/member_menu/)){ + $fleetupdate = $dbh->selectrow_array(q{SELECT tick FROM fleets WHERE sender = ? + AND mission = 'Full fleet' AND tick > tick() - 24 + },undef,$c->user->planet); + $fleetupdate = 0 unless defined $fleetupdate; + } + + my ($unread,$newposts) = $dbh->selectrow_array(unread_query,undef,$c->user->id) or die $dbh->errstr; + + $c->stash(user => { + id => $c->user->id, + name => $c->user->username, + css => $c->user->css, + newposts => $newposts, + unreadposts => $unread + }); + $c->stash->{user}->{attacker} = $c->check_user_roles(qw/attack_menu/) + && (!$c->check_user_roles(qw/member_menu/) + || ($c->user->planet && (($c->stash->{TICK} - $fleetupdate < 24) + || $c->check_user_roles(qw/no_fleet_update/)))), + $c->forward('listTargets'); + } +} =head1 AUTHOR -Catalyst developer +Michael Andreen (harv@ruin.nu) =head1 LICENSE -This library is free software, you can redistribute it and/or modify -it under the same terms as Perl itself. +GPL 2, or later. =cut diff --git a/lib/NDWeb/Include.pm b/lib/NDWeb/Include.pm new file mode 100644 index 0000000..e35567a --- /dev/null +++ b/lib/NDWeb/Include.pm @@ -0,0 +1,90 @@ +#************************************************************************** +# Copyright (C) 2006 by Michael Andreen * +# * +# This program is free software; you can redistribute it and/or modify * +# it under the terms of the GNU General Public License as published by * +# the Free Software Foundation; either version 2 of the License, or * +# (at your option) any later version. * +# * +# This program is distributed in the hope that it will be useful, * +# but WITHOUT ANY WARRANTY; without even the implied warranty of * +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# GNU General Public License for more details. * +# * +# You should have received a copy of the GNU General Public License * +# along with this program; if not, write to the * +# Free Software Foundation, Inc., * +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * +#**************************************************************************/ + +package NDWeb::Include; +use strict; +use warnings; +require Exporter; +use BBCode::Parser; + +our @ISA = qw/Exporter/; + +our @EXPORT = qw/parseMarkup min max + alliances intelquery /; + +sub parseMarkup ($) { + my ($text) = @_; + + #$text =~ s{\n}{\n
}g; + #$text =~ s{\[B\](.*?)\[/B\]}{$1}gi; + #$text =~ s{\[I\](.*?)\[/I\]}{$1}gi; + #$text =~ s{\[url\](.*?)\[/url\]}{$1}gi; + #$text =~ s{\[PRE\](.*?)\[/PRE\]}{
$1
}sgi; + #$text =~ s{\[PRE\](.*?)\[/PRE\]}{
$1
}sgi; + #$1 =~ s{
}{}g; + + eval{ + my $tree = BBCode::Parser->DEFAULT->parse($text); + $text = $tree->toHTML; + }; + $text =~ s/\x{3}\d\d?//g; #mirc color TODO: possibly match until \x{0F} and change to [color] block + $text =~ s/[^\x{9}\x{A}\x{D}\x{20}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]//g; + return $text; +} + + +sub min { + my ($x,$y) = @_; + return ($x > $y ? $y : $x); +} + +sub max { + my ($x,$y) = @_; + return ($x < $y ? $y : $x); +} + + +sub alliances { + my ($alliance) = @_; + my @alliances; + $alliance = -1 unless defined $alliance; + push @alliances,{Id => -1, Name => '', Selected => not $alliance}; + my $query = $ND::DBH->prepare(q{SELECT id,name FROM alliances ORDER BY LOWER(name)}); + $query->execute; + while (my $ally = $query->fetchrow_hashref){ + push @alliances,{Id => $ally->{id}, Name => $ally->{name}, Selected => $alliance == $ally->{id}}; + } + return @alliances; +} + +sub intelquery { + my ($columns,$where) = @_; + return qq{ +SELECT $columns, i.mission, i.tick AS landingtick,MIN(i.eta) AS eta, i.amount, i.ingal, u.username +FROM (fleets i NATURAL JOIN users u) + JOIN current_planet_stats t ON i.target = t.id + JOIN current_planet_stats o ON i.sender = o.id +WHERE $where +GROUP BY i.tick,i.mission,t.x,t.y,t.z,o.x,o.y,o.z,i.amount,i.ingal,u.username,t.alliance,o.alliance,t.nick,o.nick +ORDER BY i.tick DESC, i.mission}; +} + + + +1; diff --git a/lib/NDWeb/View/TT.pm b/lib/NDWeb/View/TT.pm index fc22bae..b0f8571 100644 --- a/lib/NDWeb/View/TT.pm +++ b/lib/NDWeb/View/TT.pm @@ -14,6 +14,7 @@ __PACKAGE__->config({ TIMER => 0, #DEBUG => 'undef', TEMPLATE_EXTENSION => '.tt2', + #CACHE_SIZE => 256, }); =head1 NAME diff --git a/root/lib/config/main.tt2 b/root/lib/config/main.tt2 index 2e9bcfd..5b30aa4 100644 --- a/root/lib/config/main.tt2 +++ b/root/lib/config/main.tt2 @@ -7,7 +7,7 @@ IF c.debug; # define a debug() macro directed to Catalyst's log - MACRO debug(message) CALL Catalyst.log.debug(message); + MACRO debug(message) CALL c.log.debug(message); END; # define a data structure to hold sitewide data diff --git a/root/lib/inc/targetlist.tt2 b/root/lib/inc/targetlist.tt2 new file mode 100644 index 0000000..4b1890f --- /dev/null +++ b/root/lib/inc/targetlist.tt2 @@ -0,0 +1,20 @@ +[% IF targets%] + + + [% FOR target IN targets %] + + + + + + [% END %] +
TargetTick
+ [% target.released_coords and target.coords%][% IF target.launched%]*[% END %] + [% target.landingtick %] + + +
+[% END %] diff --git a/root/lib/site/html.tt2 b/root/lib/site/html.tt2 index 8cccb3f..91fbff0 100644 --- a/root/lib/site/html.tt2 +++ b/root/lib/site/html.tt2 @@ -1,17 +1,15 @@ - - - + + [% site.title %]: [% template.title %] - - - - + + + + - [% content %] + diff --git a/root/lib/site/layout.tt2 b/root/lib/site/layout.tt2 index ec17e5f..2c11d74 100644 --- a/root/lib/site/layout.tt2 +++ b/root/lib/site/layout.tt2 @@ -2,6 +2,11 @@
+[% IF error %] +
+ [% error %] +
+[% END %] [% content %]
diff --git a/root/lib/site/leftbar.tt2 b/root/lib/site/leftbar.tt2 index 3714285..e69075e 100644 --- a/root/lib/site/leftbar.tt2 +++ b/root/lib/site/leftbar.tt2 @@ -1,14 +1,25 @@

Tick: [% game.tick %]

-[% IF user.isMember %] - [% IF user.isAttacker %] +[% IF c.check_user_roles("member_menu") %] + [% IF user.attacker %]

Member menu

[% ELSE %] - [% IF user.planet %] + [% IF c.user.planet %]

Update your fleet to see member menu

[% ELSE %] -
+

We need your planet's coordinates: - - + +

[% END %] [% END %] [% END %] -[% IF user.isAttacker %] +[% IF user.attacker %]

Attack menu

-
+

+

+
[% PROCESS inc/targetlist.tt2 %]
[% END %] -[% IF user.isBC %] +[% IF c.check_user_roles("bc_menu") %]

BC menu

[% END %] -[% IF user.isDC %] +[% IF c.check_user_roles("dc_menu") %]

DC menu

[% END %] -[% IF user.isHC %] +[% IF c.check_user_roles("intel_menu") %] +

Intel menu

+ +[% END %] +[% IF c.check_user_roles("hc_menu") %]

HC menu

-[% ELSE %] - [% IF user.isIntel %] -

Intel menu

- - [% END %] [% END %] diff --git a/root/src/access_denied.tt2 b/root/src/access_denied.tt2 new file mode 100644 index 0000000..df5bbdb --- /dev/null +++ b/root/src/access_denied.tt2 @@ -0,0 +1 @@ +

Access Denied

diff --git a/root/static/default.css b/root/static/default.css index 9349e08..3275e9f 100644 --- a/root/static/default.css +++ b/root/static/default.css @@ -94,8 +94,11 @@ ul.linkbar a { width: 100%; display: block; } -input.coordsinput { - width: 4em; +ul.linkbar input { + width: 12em; +} +ul.linkbar input.coordsinput { + width: 5em; } input.small { width: 1.7em; diff --git a/templates/NoAccess.tmpl b/templates/NoAccess.tmpl deleted file mode 100644 index df5bbdb..0000000 --- a/templates/NoAccess.tmpl +++ /dev/null @@ -1 +0,0 @@ -

Access Denied

diff --git a/templates/targetlist.tmpl b/templates/targetlist.tmpl deleted file mode 100644 index 3a2e6e0..0000000 --- a/templates/targetlist.tmpl +++ /dev/null @@ -1,23 +0,0 @@ -

-

- - - - - - - - - - -
TargetTick
* - U - - ',,,'Unclaim')"/> - ',,,'set&joinable=')"/> - -
-