summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2017-09-22 12:59:27 +0200
committerSergey Poznyakoff <gray@gnu.org>2017-09-22 14:36:28 +0200
commitc990008d564dbaf4f8881458224b7ecaac104f07 (patch)
tree805cab4728f4170783e63c95efe0b37aa586b188
parent0615ed0ff77ba49a919edf9274a8933872f6f403 (diff)
downloadsourceyard-c990008d564dbaf4f8881458224b7ecaac104f07.tar.gz
sourceyard-c990008d564dbaf4f8881458224b7ecaac104f07.tar.bz2
Start implementing user personal pages
* lib/Sourceyard.pm: Predeclare user and return_url stash vars. Route user/ requests. * lib/Sourceyard/Controller.pm (clone): New method. * lib/Sourceyard/Controller/Account.pm (login): Redirect to / if already authenticated. (user_login): Redirect to return_url, defaulting to /. * lib/Sourceyard/Controller/Main.pm: Don't use is_logged_in. * lib/Sourceyard/Controller/User.pm: New file. * lib/Sourceyard/Schema/Result/User.pm: Load InflateColumn::DateTime. Index on user_name. * templates/account/login.html.ep: Move feedback div to include/feedback.html.ep. Include it. * templates/include/feedback.html.ep: New file. * templates/layouts/default.html.ep: Omit div.indexright if statistics stash var is not defined. * templates/layouts/user.html.ep: New file. * templates/menu/anonmenu.html.ep * templates/menu/leftmenu.html.ep: Use the 'user' stash var instead of is_logged_in * templates/menu/topuser.html.ep: New file. * templates/menu/usermenu.html.ep: Use absolute locations. * templates/user/admin.html.ep: New file.
-rw-r--r--lib/Sourceyard.pm14
-rw-r--r--lib/Sourceyard/Controller.pm7
-rw-r--r--lib/Sourceyard/Controller/Account.pm15
-rw-r--r--lib/Sourceyard/Controller/Main.pm7
-rw-r--r--lib/Sourceyard/Controller/User.pm11
-rw-r--r--lib/Sourceyard/Schema/Result/User.pm2
-rw-r--r--templates/account/login.html.ep55
-rw-r--r--templates/include/feedback.html.ep8
-rw-r--r--templates/layouts/default.html.ep4
-rw-r--r--templates/layouts/user.html.ep24
-rw-r--r--templates/menu/anonmenu.html.ep4
-rw-r--r--templates/menu/leftmenu.html.ep17
-rw-r--r--templates/menu/topuser.html.ep38
-rw-r--r--templates/menu/usermenu.html.ep7
-rw-r--r--templates/user/admin.html.ep78
15 files changed, 244 insertions, 47 deletions
diff --git a/lib/Sourceyard.pm b/lib/Sourceyard.pm
index 7b7d92d..4d1a528 100644
--- a/lib/Sourceyard.pm
+++ b/lib/Sourceyard.pm
@@ -3,6 +3,7 @@ use Mojo::Base 'Mojolicious';
use FindBin;
use Sourceyard::Config;
use Sourceyard::Schema;
+use Sourceyard::Controller;
my @allowed = qw(
193.186.15.43
@@ -34,6 +35,9 @@ sub startup {
# FIXME: Documentation browser under "/perldoc"
$self->plugin('PODRenderer');
+ $self->app->defaults(user => undef);
+ $self->app->defaults(return_url => undef);
+
# Router
my $r = $self->routes;
@@ -41,6 +45,16 @@ sub startup {
$r->get('/')->to('main#index');
$r->get('/account/:action')->to(controller => 'account');
$r->post('/account/login')->name('login')->to('account#user_login');
+
+ my $auth = $r->under('/user' => sub {
+ my $c = Sourceyard::Controller->clone(shift);
+ unless ($c->stash('user')) {
+ $c->render('/account/login', return_url => $c->req->url);
+ return undef
+ }
+ return 1;
+ });
+ $auth->get(':action')->to(controller => 'user');
}
1;
diff --git a/lib/Sourceyard/Controller.pm b/lib/Sourceyard/Controller.pm
index e7cdd2f..17f887c 100644
--- a/lib/Sourceyard/Controller.pm
+++ b/lib/Sourceyard/Controller.pm
@@ -13,6 +13,13 @@ sub new {
return $self;
}
+sub clone {
+ my ($class,$obj) = @_;
+ my $self = bless $obj, $class;
+ $self->set_user;
+ return $self;
+}
+
sub set_user {
my ($self, $user) = @_;
if (defined($user)) {
diff --git a/lib/Sourceyard/Controller/Account.pm b/lib/Sourceyard/Controller/Account.pm
index 66cd2ba..fe65008 100644
--- a/lib/Sourceyard/Controller/Account.pm
+++ b/lib/Sourceyard/Controller/Account.pm
@@ -5,7 +5,12 @@ use Sourceyard::User;
sub login {
my $self = shift;
- $self->render(is_logged_in => 0);
+ if ($self->stash('user')) {
+ $self->res->code(302);
+ $self->redirect_to('/');
+ return;
+ }
+ $self->render;
}
sub logout {
@@ -31,7 +36,8 @@ sub user_login {
my $username = $self->param('username');
my $password = $self->param('password');
my $remember = $self->param('cookie_for_a_year');
-
+ my $return_url = $self->param('return_url') || '/';
+
my $user = new Sourceyard::User($self, $username);
if ($user && $self->pwcheck($password, $user->user_pw)) {
# FIXME
@@ -40,12 +46,9 @@ sub user_login {
# $res->update;
# }
$self->set_user($user);
-
- $self->res->code(302);
- $self->redirect_to('/');
+ $self->redirect_to($return_url);
} else {
$self->render('account/login',
- is_logged_in => 0,
error_msg => 'Invalid user name or password');
}
}
diff --git a/lib/Sourceyard/Controller/Main.pm b/lib/Sourceyard/Controller/Main.pm
index 64f2565..04a23d7 100644
--- a/lib/Sourceyard/Controller/Main.pm
+++ b/lib/Sourceyard/Controller/Main.pm
@@ -4,16 +4,13 @@ use Mojo::Base 'Sourceyard::Controller';
# This action will render a template
sub index {
my $self = shift;
-
$self->render(msg => 'Welcome',
- statistics => $self->statistics,
- is_logged_in => $self->session('logged_in'),
- );
+ statistics => $self->statistics);
}
sub login {
my $self = shift;
- $self->render(is_logged_in => 0);
+ $self->render;
}
1;
diff --git a/lib/Sourceyard/Controller/User.pm b/lib/Sourceyard/Controller/User.pm
new file mode 100644
index 0000000..418fd5a
--- /dev/null
+++ b/lib/Sourceyard/Controller/User.pm
@@ -0,0 +1,11 @@
+package Sourceyard::Controller::User;
+use Mojo::Base 'Sourceyard::Controller';
+use Sourceyard::User;
+
+sub admin {
+ my $self = shift;
+ print "ADMIN\n";
+ $self->render;
+}
+
+1;
diff --git a/lib/Sourceyard/Schema/Result/User.pm b/lib/Sourceyard/Schema/Result/User.pm
index adc7120..9210817 100644
--- a/lib/Sourceyard/Schema/Result/User.pm
+++ b/lib/Sourceyard/Schema/Result/User.pm
@@ -5,6 +5,7 @@ use warnings;
use base 'DBIx::Class::Core';
+__PACKAGE__->load_components(qw/ InflateColumn::DateTime Core /);
__PACKAGE__->table('user');
__PACKAGE__->add_columns(
user_id => {
@@ -58,6 +59,7 @@ __PACKAGE__->add_columns(
}
);
__PACKAGE__->set_primary_key('user_id');
+__PACKAGE__->add_unique_constraint(['user_name']);
__PACKAGE__->add_unique_constraint(['user_id','user_name']);
__PACKAGE__->add_unique_constraint(['email']);
__PACKAGE__->has_many(
diff --git a/templates/account/login.html.ep b/templates/account/login.html.ep
index 2812001..46e6944 100644
--- a/templates/account/login.html.ep
+++ b/templates/account/login.html.ep
@@ -1,30 +1,27 @@
% layout 'account';
% title 'Sourceyard Login';
-%= t h2 => (class => 'toptitle') => begin
- %= t img => (src => "/images/Savannah.theme/contexts/main.orig.png", width =>48, height => 48, alt => 'main', class => "pageicon")
+<h2 class="toptitle">
+ <img src="/images/<%= $theme %>.theme/contexts/main.orig.png"
+ width="48" height="48" alt="main" class="pageicon" />
Login
-% end
-%= t div => (class => "topmenu", id => "topmenu") => begin
- %= t span => (class => "topmenutitle", title => "Site Wide Scope") => begin
- Site Wide
- % end
-% end
-% if (my $error_msg = stash 'error_msg') {
-<div onclick="document.getElementById('feedback').style.visibility='visible'; document.getElementById('feedbackback').style.visibility='hidden';" id="feedbackback" class="feedbackback">
-Show feedback again
-</div>
-<div id="feedback" class="feedbackerror" onclick="document.getElementById('feedback').style.visibility='hidden'; document.getElementById('feedbackback').style.visibility='visible';"><span class="feedbackerrortitle"><img src="/images/Savannah.theme/bool/wrong.png" class="feedbackimage" alt="" />Error:</span><br/>
-%= $error_msg
-</div>
-% }
+</h2>
+<div class="topmenu" id="topmenu">
+ <span class="topmenutitle" title="Site Wide Scope">
+ Site Wide
+ </span>
+</div>
+%= include "include/feedback"
<div class="form">
%= form_for 'login' => (method => 'POST') => begin
+% if ($return_url) {
+%= hidden_field return_url => $return_url
+% }
<div class="input">
%= label_for username => => (class => 'preinput') => begin
Login Name:
% end
- %= text_field 'username'
- %= link_to 'register' => (class => 'smaller') => begin
+ %= text_field 'username' => (tabindex => 1)
+ %= link_to 'register' => (class => 'smaller', tabindex => 2) => begin
[No account yet?]
%= end
</div>
@@ -32,21 +29,21 @@ Show feedback again
%= label_for password => (class => 'preinput') => begin
Password:
% end
- %= password_field 'password'
- %= link_to 'lostpw' => (class => 'smaller') => begin
+ %= password_field 'password' => (tabindex => 1)
+ %= link_to 'lostpw' => (class => 'smaller', tabindex => 2) => begin
[Lost your password?]
%= end
</div>
- <div class="left">
- %= input_tag type => 'cookie_for_a_year', type => 'checkbox'
- <span class="preinput">Remember me</span><br />
- <span class="text">For a year, your login information will be stored
- in a cookie. Use this only if you are
- using your own computer.
- </span>
- </div>
+%# <div class="left">
+%# %= input_tag type => 'cookie_for_a_year', type => 'checkbox'
+%# <span class="preinput">Remember me</span><br />
+%# <span class="text">For a year, your login information will be stored
+%# in a cookie. Use this only if you are
+%# using your own computer.
+%# </span>
+%# </div>
<div class="center">
- %= submit_button 'Login', class => 'btn'
+ %= submit_button 'Login', (class => 'btn', tabindex => 1)
</div>
% end
</div>
diff --git a/templates/include/feedback.html.ep b/templates/include/feedback.html.ep
new file mode 100644
index 0000000..41a88e5
--- /dev/null
+++ b/templates/include/feedback.html.ep
@@ -0,0 +1,8 @@
+% if (my $error_msg = stash 'error_msg') {
+<div onclick="document.getElementById('feedback').style.visibility='visible'; document.getElementById('feedbackback').style.visibility='hidden';" id="feedbackback" class="feedbackback">
+Show feedback again
+</div>
+<div id="feedback" class="feedbackerror" onclick="document.getElementById('feedback').style.visibility='hidden'; document.getElementById('feedbackback').style.visibility='visible';"><span class="feedbackerrortitle"><img src="/images/Savannah.theme/bool/wrong.png" class="feedbackimage" alt="" />Error:</span><br/>
+%= $error_msg
+</div>
+% }
diff --git a/templates/layouts/default.html.ep b/templates/layouts/default.html.ep
index 110db3a..5d9106f 100644
--- a/templates/layouts/default.html.ep
+++ b/templates/layouts/default.html.ep
@@ -16,8 +16,8 @@
<div class="main"><a name="top"></a>
- <div class="indexright">
% if (my $stat = stash 'statistics') {
+ <div class="indexright">
<div class="box">
<div class="boxtitle">
<a href="/stats/" class="sortbutton">Statistics</a>
@@ -33,8 +33,8 @@
%# </span>
%# </div>
</div> <!-- box -->
-% }
</div> <!-- indexright -->
+% }
<div class="indexcenter">
<%= content %>
diff --git a/templates/layouts/user.html.ep b/templates/layouts/user.html.ep
new file mode 100644
index 0000000..89fe7e7
--- /dev/null
+++ b/templates/layouts/user.html.ep
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ lang="en-US.UTF-8" xml:lang="en-US.UTF-8">
+ <head>
+ <title><%= title %></title>
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
+ <link rel="stylesheet" type="text/css" href="/css/<%= $theme %>.css" />
+ <link rel="icon" type="image/png" href="/images/<%= $theme %>.theme/icon.png" />
+ </head>
+ <body>
+ <div class="realbody">
+%= include "menu/leftmenu"
+ <div class="main"><a name="top"></a>
+%= include "menu/topuser"
+ <div id="topmenunooverlap">&nbsp;</div>
+ <div id="topmenunooverlapbis">&nbsp;</div>
+ <%= content %>
+ </div> <!-- main -->
+ </div> <!-- realbody -->
+ </body>
+</html>
diff --git a/templates/menu/anonmenu.html.ep b/templates/menu/anonmenu.html.ep
index 4be7419..b6ad067 100644
--- a/templates/menu/anonmenu.html.ep
+++ b/templates/menu/anonmenu.html.ep
@@ -5,9 +5,9 @@
<li class="menuitem">
<span class="error">Not Logged In</span>
<li class="menuitem">
- %= link_to Login => 'account/login'
+ %= link_to Login => '/account/login'
</li>
<li class="menuitem">
- %= link_to 'New User' => 'account/register'
+ %= link_to 'New User' => '/account/register'
</li>
</li>
diff --git a/templates/menu/leftmenu.html.ep b/templates/menu/leftmenu.html.ep
index f3e981b..f6c8549 100644
--- a/templates/menu/leftmenu.html.ep
+++ b/templates/menu/leftmenu.html.ep
@@ -6,11 +6,26 @@
height="125" />
</a>
</li>
-% if ($is_logged_in) {
+% if ($user) {
%= include "menu/usermenu"
% } else {
%= include "menu/anonmenu"
% }
+
+ <li class="menutitle">
+ Search
+ </li><!-- end menutitle -->
+ <li class="menusearch">
+%= form_for '/search' => (method => 'POST') => begin
+%= text_field 'words' => (size => 15)
+<br/>
+<em>in</em>
+%= select_field type_of_search => [[ Projects => 'projects', selected => 'selected'], [ People => 1]]
+<br/>
+%= submit_button 'Search', class => 'btn'
+% end
+ </li>
+
<li class="menutitle">
Related Forges
</li>
diff --git a/templates/menu/topuser.html.ep b/templates/menu/topuser.html.ep
new file mode 100644
index 0000000..11003ce
--- /dev/null
+++ b/templates/menu/topuser.html.ep
@@ -0,0 +1,38 @@
+<h2 class="toptitle">
+ <img src="/images/<%= $theme %>.theme/contexts/preferences.orig.png"
+ width="48" height="48" alt="preferences" class="pageicon" />
+ My Account Configuration
+</h2>
+
+<div class="topmenu" id="topmenu">
+ <span class="topmenutitle" title="My Scope">
+ My
+ </span><!-- end topmenutitle -->
+<div class="topmenuitem">
+<ul id="topmenuitem">
+ <li class="topmenuitemmainitem">
+ <a href="/user/" class="tabs" title="What's new for me?">
+ Incoming Items
+ </a>
+ </li><!-- end topmenuitemmainitem -->
+
+ <li class="topmenuitemmainitem">
+ <a href="/user/items.php" class="tabs" title="Browse my items (bugs, tasks, bookmarks...)">
+ Items
+ </a>
+ </li><!-- end topmenuitemmainitem -->
+
+ <li class="topmenuitemmainitem">
+ <a href="/user/groups.php" class="tabs" title="List the groups I belong to">
+ Group Membership
+ </a>
+ </li><!-- end topmenuitemmainitem -->
+
+ <li class="topmenuitemmainitem">
+ <a href="/user/admin/" class="tabselect" title="Account configuration: authentication, cosmetics preferences...">
+ Account Configuration
+ </a>
+ </li><!-- end topmenuitemmainitem -->
+</ul>
+</div><!-- end topmenuitem -->
+</div>
diff --git a/templates/menu/usermenu.html.ep b/templates/menu/usermenu.html.ep
index 8aed663..326b3a6 100644
--- a/templates/menu/usermenu.html.ep
+++ b/templates/menu/usermenu.html.ep
@@ -1,6 +1,9 @@
<li class="menutitle">
- Logged in as <%= $self->session('username') %>
+ Logged in as <%= $user->user_name %>
</li>
<li class="menuitem">
- %= link_to Logout => 'account/logout'
+ %= link_to 'My Account Conf' => '/user/admin'
+</li>
+<li class="menuitem">
+ %= link_to Logout => '/account/logout'
</li>
diff --git a/templates/user/admin.html.ep b/templates/user/admin.html.ep
new file mode 100644
index 0000000..2a621b0
--- /dev/null
+++ b/templates/user/admin.html.ep
@@ -0,0 +1,78 @@
+% layout 'user';
+% title 'My Account Configuration';
+%= include "include/feedback"
+<div class="form">
+%= form_for 'admin' => (method => 'POST') => begin
+ <h3>Significant Arrangements</h3>
+ <div class="splitleft">
+ <div class="box">
+ <div class="boxtitle">Identity Record</div>
+ <div class="boxitem">
+ Account #<%= $user->user_id %>
+ <p class="smaller">
+ Your login is <strong><%= $user->user_name %></strong>.
+ You registered your account on
+% $user->add_date->set_time_zone('local');
+ <strong><%= $user->add_date->strftime('%a %d %b %Y %I:%M:%S %p %z') %></strong>.
+ </p>
+ </div><!-- end ---- boxitem -->
+ <div class="boxitemalt">
+ <a href="change.php?item=realname">Change Real Name</a>
+ <p class="smaller">
+ You are <strong><%= $user->real_name %></strong>.
+ </p>
+ </div><!-- end ---- boxitem -->
+ <div class="boxitem">
+ <a href="resume.php">Edit Resume and Skills</a>
+ <p class="smaller">
+ Details about your experience and skills will be available to
+ logged in users in the hope they will be of interest.
+ </p>
+ </div><!-- end ---- boxitem -->
+ <div class="boxitemalt">
+ <a href="/users/gray">View your Public Profile</a>
+ <p class="smaller">
+ Your profile can be viewed by everybody.
+ </p>
+ </div><!-- end ---- boxitem -->
+ </div><!-- end box -->
+ <br />
+ <div class="box">
+ <div class="boxtitle">Mail Setup</div>
+ <div class="boxitem">
+ <a href="change.php?item=email">
+ Change Email Address
+ </a>
+ <p class="smaller">
+ Your current address is
+ <strong><%= $user->email %></strong>.
+ It is essential to us that this address remains valid. Keep
+ it up to date.
+ </p>
+ </div><!-- end boxitem -->
+ <div class="boxitemalt">
+ <a href="change_notifications.php">
+ Edit Personal Notification Settings
+ </a>
+ <p class="smaller">
+ Configure when the trackers should send email notifications.
+ It permits also to configure the subject line prefix of sent
+ mails.
+ </p>
+ </div><!-- end ---- boxitem -->
+ <div class="boxitem">
+ <a href="cc.php">
+ Cancel Mail Notifications
+ </a>
+ <p class="smaller">
+ Here, you can cancel all mail notifications.
+ </p>
+ </div><!-- end ---- boxitem -->
+ </div><!-- end box -->
+ <br />
+ </div><!-- end splitleft -->
+ <div class="center">
+ %= submit_button 'Update', (class => 'btn', tabindex => 1)
+ </div>
+% end
+

Return to:

Send suggestions and report system problems to the System administrator.