Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'release/v0.21'

  • Loading branch information...
commit b7e33a74a0fc66dbfe306dca367afd2a3197ee68 2 parents e79ae82 + bc62ff5
@szabgab authored
View
1  .gitignore
@@ -6,6 +6,7 @@ pm_to_blib
MANIFEST
MANIFEST.bak
MYMETA.yml
+MYMETA.json
META.yml
META.json
/inc
View
42 Changes
@@ -1,23 +1,39 @@
+Changes to the Dwimmer system. See http://dwimmer.org/
+
+ - Move the site checking to the 'before' hook to eliminate duplication.
+ - Use the _clean_params function instaed of manual implementations.
+ - Allow changing password. #21
+ - Show old version when clicking on link in history #18
+ - Add pagination to the list of pages #14
+ - dwimmer_setup.pl can now set the password of any user #25
+ - by default display login form when not logged in #26
+ - and allow the admin to change this setting per site #26
+ - by default hide experimental features, allow admin to show them #27
+ - add link to be able to manege current site #28
+ - add sitemap.xml listing all the pages #23
+
v0.20 2011.10.25
- Add jquery.a-tools-1.5.2 plugin.
- Add B(old) and I(talic) buttons to editor.
- Add jquery-ui-1.8.16.custom.min.js
+ - Add jquery.a-tools-1.5.2 plugin.
+ - Add B(old) and I(talic) buttons to editor.
+ - Add jquery-ui-1.8.16.custom.min.js
- Enable [http://address] and [https://address].
+ - Enable [http://address] and [https://address].
- Add script/dwimmer to enable adding user from the command line.
- Enable some special characters in the filename: space ( ), dot (.), $, @ and %.
- Eliminate cache from the Ajax get requests as IE (both 8 and 9) would cache by default.
+ - Add script/dwimmer to enable adding user from the command line.
+ - Enable some special characters in the filename:
+ space ( ), dot (.), $, @ and %.
+ - Eliminate cache from the Ajax get requests as IE (both 8 and 9)
+ would cache by default.
- Replace several methods in the Dwimmer::Client or change their APIs
- most importantly 'login', 'get_page',
- Add site_config table
- Add Google Analytics and GetClicky
+ - Replace several methods in the Dwimmer::Client or change their APIs
+ most importantly 'login', 'get_page',
+ - Add site_config table
+ - Add Google Analytics and GetClicky
- Probably lots of other things I forgot to add to the Changes file.
+ - Probably lots of other things I forgot to add to the Changes file.
v0.11 2011.09.10
- Release of the first interesting version.
+ - Release of the first interesting version.
View
2  MANIFEST.SKIP
@@ -13,7 +13,7 @@
\bpm_to_blib$
\bblibdirs$
^MANIFEST\.SKIP$
-MYMETA\.(?:yaml|json)$
+MYMETA\.(?:yml|yaml|json)$
# Avoid Module::Build generated and utility files.
View
68 Makefile.PL
@@ -12,47 +12,47 @@ configure_requires 'ExtUtils::MakeMaker' => '6.52';
configure_requires 'File::Copy::Recursive' => 0;
configure_requires 'File::Spec' => 0;
-name 'Dwimmer';
-license 'perl';
-author 'Gabor Szabo <szabgab@dwimmer.org>';
+name 'Dwimmer';
+license 'perl';
+author 'Gabor Szabo <szabgab@dwimmer.org>';
all_from 'lib/Dwimmer.pm';
requires 'perl' => '5.008005';
my %prereq = (
- 'autodie' => 0,
- 'Dancer' => 1.3060,
- 'Data::Dumper' => 0,
- 'DBIx::Class' => 0,
- 'DBIx::Class::Schema' => 0,
- 'DBIx::RunSQL' => 0,
- 'Email::Valid' => 0,
- 'Encode' => 0,
- 'File::ShareDir' => '1.00',
- 'File::Slurp' => 0,
- 'Getopt::Long' => 0,
- 'JSON' => 0,
- 'MIME::Lite' => 0,
- 'Moose' => 0,
- 'Pod::Usage' => 0,
- 'String::Random' => 0,
- 'Template' => 0,
- 'XML::Feed' => 0,
- 'XML::RSS' => 0,
- 'YAML' => 0,
+ 'autodie' => 0,
+ 'Dancer' => 1.3060,
+ 'Data::Dumper' => 0,
+ 'DBIx::Class' => 0,
+ 'DBIx::Class::Schema' => 0,
+ 'DBIx::RunSQL' => 0,
+ 'Email::Valid' => 0,
+ 'Encode' => 0,
+ 'File::ShareDir' => '1.00',
+ 'File::Slurp' => 0,
+ 'Getopt::Long' => 0,
+ 'JSON' => 0,
+ 'MIME::Lite' => 0,
+ 'Moose' => 0,
+ 'Pod::Usage' => 0,
+ 'String::Random' => 0,
+ 'Template' => 0,
+ 'XML::Feed' => 0,
+ 'XML::RSS' => 0,
+ 'YAML' => 0,
);
-if ($^O =~ /win32/i) {
- $prereq{'Win32::Process'} = 0;
+if ( $^O =~ /win32/i ) {
+ $prereq{'Win32::Process'} = 0;
}
-foreach my $module (keys %prereq) {
- requires $module => $prereq{$module};
+foreach my $module ( keys %prereq ) {
+ requires $module => $prereq{$module};
}
-test_requires 'Test::More' => 0;
-test_requires 'Test::Deep' => 0;
-test_requires 'Test::WWW::Mechanize' => 0;
+test_requires 'Test::More' => 0;
+test_requires 'Test::Deep' => 0;
+test_requires 'Test::WWW::Mechanize' => 0;
homepage 'http://dwimmer.org/';
@@ -65,13 +65,13 @@ install_script 'script/dwimmer';
# Copy files to share before installing (but it is not included in the distribution)
foreach my $module (qw(File::Copy::Recursive File::Spec)) {
- eval "use $module";
- die "Need to install $module before running Makefile.PL again\n" if $@;
+ eval "use $module";
+ die "Need to install $module before running Makefile.PL again\n" if $@;
}
foreach my $dir (qw(bin views schema public environments)) {
- File::Copy::Recursive::dircopy( $dir, File::Spec->catdir('share', $dir) );
+ File::Copy::Recursive::dircopy( $dir, File::Spec->catdir( 'share', $dir ) );
}
-File::Copy::Recursive::fcopy('config.yml', 'share');
+File::Copy::Recursive::fcopy( 'config.yml', 'share' );
install_share;
View
246 lib/Dwimmer.pm
@@ -3,7 +3,7 @@ use Dancer ':syntax';
use 5.008005;
-our $VERSION = '0.20';
+our $VERSION = '0.21';
use Data::Dumper qw(Dumper);
use Dwimmer::DB;
@@ -16,65 +16,106 @@ load_app 'Dwimmer::Admin', prefix => "/_dwimmer";
# list of pages that can be accessed withot any login
my %open = map { $_ => 1 } qw(
- /poll
- /_dwimmer/login.json
- /_dwimmer/session.json
- /_dwimmer/register_email.json /_dwimmer/register_email
- /_dwimmer/validate_email.json /_dwimmer/validate_email
+ /poll
+ /_dwimmer/login.json
+ /_dwimmer/session.json
+ /_dwimmer/register_email.json /_dwimmer/register_email
+ /_dwimmer/validate_email.json /_dwimmer/validate_email
);
hook before => sub {
- my $path = request->path_info;
+ my $path = request->path_info;
+
+ # debug(request->uri);
my $db = _get_db();
- my ($version) = $db->storage->dbh->selectrow_array('PRAGMA user_version');
+ my ($version) = $db->storage->dbh->selectrow_array('PRAGMA user_version');
+
#see also do_dbh https://metacpan.org/module/DBIx::Class::Storage::DBI#dbh_do
- if ($version != $SCHEMA_VERSION) {
+ if ( $version != $SCHEMA_VERSION ) {
return halt("Database is currently at version $version while we need version $SCHEMA_VERSION");
}
+ my ( $site_name, $site ) = _get_site();
+ return halt("Could not find site called '$site_name' in the database") if not $site;
+
+ # TODO send text or json whatever is appropriate
+ # return to_json { error => 'no_site_found' } if not $site;
- return if $open{$path};
- return if $path !~ m{/_}; # only the pages starting with /_ are management pages that need restriction
-
- if (not session->{logged_in}) {
- if ($path =~ /json$/) {
- request->path_info('/_dwimmer/needs_login.json');
- } else {
- request->path_info('/_dwimmer/needs_login');
- }
- }
- return;
+ return if $open{$path};
+ return if $path !~ m{/_}; # only the pages starting with /_ are management pages that need restriction
+
+ if ( not session->{logged_in} ) {
+ if ( $path =~ /json$/ ) {
+ request->path_info('/_dwimmer/needs_login.json');
+ } else {
+ request->path_info('/_dwimmer/needs_login');
+ }
+ }
+ return;
};
sub route_index {
- my ($site_name, $site) = _get_site();
- return "Could not find site called '$site_name' in the database" if not $site;
-
- my $path = request->path_info;
- my $data = Dwimmer::Admin::get_page_data($site, $path);
-
- if ($data) {
- if ($data->{body} =~ s{\[poll://([^]]+)\]}{}) {
- my $poll = $1;
- if (not params->{submitted}) {
- $data->{body} = _poll($poll);
- }
- }
-
- $data->{body} =~ s{\[(\w+)://([^]]+)\]}{_process($1, $2)}eg;
-
- $data->{body} =~ s{\[([\w .\$@%-]+)\]}{<a href="$1">$1</a>}g;
- return Dwimmer::Admin::render_response('index', { page => $data });
- } else {
- # TODO: actually this should check if the user has the right to create a new page
- # on this site
- if (session->{logged_in}) {
- return Dwimmer::Admin::render_response('error', { page_does_not_exist => 1, creation_offer => 1 });
- } else {
- return Dwimmer::Admin::render_response('error', { page_does_not_exist => 1 });
- }
- }
+ my ( $site_name, $site ) = _get_site();
+
+ my $path = request->path_info;
+ my $data = Dwimmer::Admin::get_page_data( $site, $path );
+
+ if ($data) {
+ if ( $data->{body} =~ s{\[poll://([^]]+)\]}{} ) {
+ my $poll = $1;
+ if ( not params->{submitted} ) {
+ $data->{body} = _poll($poll);
+ }
+ }
+
+ $data->{body} =~ s{\[(\w+)://([^]]+)\]}{_process($1, $2)}eg;
+
+ $data->{body} =~ s{\[([\w .\$@%-]+)\]}{<a href="$1">$1</a>}g;
+ return Dwimmer::Admin::render_response( 'index', { page => $data } );
+ } else {
+
+ # TODO: actually this should check if the user has the right to create a new page
+ # on this site
+ if ( session->{logged_in} ) {
+ return Dwimmer::Admin::render_response( 'error', { page_does_not_exist => 1, creation_offer => 1 } );
+ } else {
+ return Dwimmer::Admin::render_response( 'error', { page_does_not_exist => 1 } );
+ }
+ }
+}
+
+# http://www.sitemaps.org/protocol.html
+get '/sitemap.xml' => sub {
+
+ # see also Dwimmer::Admin get_pages.json
+ my $db = _get_db();
+ my ( $site_name, $site ) = _get_site();
+ my @res = $db->resultset('Page')->search( { siteid => $site->id } );
+
+ # lastmode => YYYY-MM-DD
+ # changefreq
+ # priority
+ my $host = request->uri_base;
+ my @urls = map { { loc => [ $host . $_->filename ] } } @res;
+
+ my %urlset = (
+ xmlns => 'http://www.sitemaps.org/schemas/sitemap/0.9',
+ url => \@urls
+ );
+
+ require XML::Simple;
+ my $xs = XML::Simple->new(
+ KeepRoot => 1,
+ ForceArray => 0,
+ KeyAttr => { urlset => 'xmlns' },
+ XMLDecl => '<?xml version="1.0" encoding="UTF-8"?>'
+ );
+ my $xml = $xs->XMLout( { urlset => \%urlset } );
+
+ content_type "text/xml";
+ return $xml;
};
+
get qr{^/([a-zA-Z0-9][\w .\$@%-]*)?$} => \&route_index;
# TODO plan:
@@ -84,68 +125,71 @@ get qr{^/([a-zA-Z0-9][\w .\$@%-]*)?$} => \&route_index;
# actually this probbaly should be shown only if we get a parmater in the get request.
# and the whole thing will be replaced by the result page once the poll is closed.
post '/poll' => sub {
- my $id = params->{id};
- return Dwimmer::Admin::render_response('error', { invalid_poll_id => $id })
- if $id !~ /^[\w-]+$/;
-
- my $json_file = path(config->{appdir}, 'polls', "$id.json");
- return Dwimmer::Admin::render_response('error', { poll_not_found => $id })
- if not -e $json_file;
-
- my $log_file = path(config->{appdir}, 'polls', "$id.txt");
- my %data = params();
- $data{IP} = request->address;
- $data{TS} = time;
- $data{SID} = session->id;
- if (open my $fh, '>>', $log_file) {
- flock($fh, LOCK_EX);
- print $fh to_json(\%data), "\n";
- close $fh;
- }
- redirect request->uri_base . "/$id?submitted=1";
+ my $id = params->{id};
+ return Dwimmer::Admin::render_response( 'error', { invalid_poll_id => $id } )
+ if $id !~ /^[\w-]+$/;
+
+ my $json_file = path( config->{appdir}, 'polls', "$id.json" );
+ return Dwimmer::Admin::render_response( 'error', { poll_not_found => $id } )
+ if not -e $json_file;
+
+ my $log_file = path( config->{appdir}, 'polls', "$id.txt" );
+ my %data = params();
+ $data{IP} = request->address;
+ $data{TS} = time;
+ $data{SID} = session->id;
+ if ( open my $fh, '>>', $log_file ) {
+ flock( $fh, LOCK_EX );
+ print $fh to_json( \%data ), "\n";
+ close $fh;
+ }
+ redirect request->uri_base . "/$id?submitted=1";
};
sub _poll {
- my ($action) = @_;
- if ($action !~ m{^[\w-]+$}) {
- return qq{Invalid poll name "$action"};
- }
- my $json_file = path(config->{appdir}, 'polls', "$action.json");
-
- if (not -e $json_file) {
- debug("File '$json_file' not found");
- return "Poll Not found";
- }
- my $data = eval { from_json scalar read_file $json_file };
- if ($@) {
- debug("Could not read json file '$json_file': $@");
- return "Could not read poll data";
- }
-
- my $html;
- open my $out, '>', \$html or die;
- my $t = Template->new(
- ABSOLUTE => 1,
-# encoding: 'utf8'
- START_TAG => '<%',
- END_TAG =>'%>',
- );
- #return path(config->{appdir}, 'views', 'poll.tt') . -s path(config->{appdir}, 'views', 'poll.tt');
- $t->process(path(config->{appdir}, 'views', 'poll.tt'), {poll => $data}, $out);
- #use Capture::Tiny qw();
- #my ($out, $err) = Capture::Tiny::capture { $t->process(path(config->{appdir}, 'views', 'poll.tt'), {poll => $data}) };
- close $out;
- return $html;
+ my ($action) = @_;
+ if ( $action !~ m{^[\w-]+$} ) {
+ return qq{Invalid poll name "$action"};
+ }
+ my $json_file = path( config->{appdir}, 'polls', "$action.json" );
+
+ if ( not -e $json_file ) {
+ debug("File '$json_file' not found");
+ return "Poll Not found";
+ }
+ my $data = eval { from_json scalar read_file $json_file };
+ if ($@) {
+ debug("Could not read json file '$json_file': $@");
+ return "Could not read poll data";
+ }
+
+ my $html;
+ open my $out, '>', \$html or die;
+ my $t = Template->new(
+ ABSOLUTE => 1,
+
+ # encoding: 'utf8'
+ START_TAG => '<%',
+ END_TAG => '%>',
+ );
+
+ #return path(config->{appdir}, 'views', 'poll.tt') . -s path(config->{appdir}, 'views', 'poll.tt');
+ $t->process( path( config->{appdir}, 'views', 'poll.tt' ), { poll => $data }, $out );
+
+ #use Capture::Tiny qw();
+ #my ($out, $err) = Capture::Tiny::capture { $t->process(path(config->{appdir}, 'views', 'poll.tt'), {poll => $data}) };
+ close $out;
+ return $html;
}
sub _process {
- my ($scheme, $action) = @_;
- if ($scheme eq 'http' or $scheme eq 'https') {
- return qq{<a href="$scheme://$action">$action</a>};
- }
+ my ( $scheme, $action ) = @_;
+ if ( $scheme eq 'http' or $scheme eq 'https' ) {
+ return qq{<a href="$scheme://$action">$action</a>};
+ }
- return qq{Unknown scheme: "$scheme"};
+ return qq{Unknown scheme: "$scheme"};
}
true;
View
1,007 lib/Dwimmer/Admin.pm
@@ -3,617 +3,630 @@ use Dancer ':syntax';
use 5.008005;
-our $VERSION = '0.20';
+our $VERSION = '0.21';
-use Data::Dumper qw(Dumper);
-use Email::Valid ();
-use MIME::Lite ();
-use String::Random ();
-use Template ();
+use Data::Dumper qw(Dumper);
+use Email::Valid ();
+use MIME::Lite ();
+use String::Random ();
+use Template ();
use Dwimmer::DB;
use Dwimmer::Tools qw(sha1_base64 _get_db _get_site save_page create_site read_file trim);
sub include_session {
- my ($data) = @_;
+ my ($data) = @_;
- if (session->{logged_in}) {
- foreach my $field (qw(logged_in username userid)) {
- $data->{$field} = session->{$field};
- };
- }
+ if ( session->{logged_in} ) {
+ foreach my $field (qw(logged_in username userid)) {
+ $data->{$field} = session->{$field};
+ }
+ }
- return;
+ return;
}
sub render_response {
- my ($template, $data) = @_;
+ my ( $template, $data ) = @_;
- $data ||= {};
- include_session($data);
+ $data ||= {};
+ include_session($data);
- debug('render_response ' . request->content_type );
- $data->{dwimmer_version} = $VERSION;
+ debug( 'render_response ' . request->content_type );
+ $data->{dwimmer_version} = $VERSION;
- my ($site_name, $site) = _get_site();
- my $db = _get_db();
+ my ( $site_name, $site ) = _get_site();
+ my $db = _get_db();
my $google_analytics = $db->resultset('SiteConfig')->find( { siteid => $site->id, name => 'google_analytics' } );
+
# TODO enable_google_analytics
if ($google_analytics) {
- $data->{google_analytics} = $google_analytics->value;
+ $data->{google_analytics} = $google_analytics->value;
}
my $getclicky = $db->resultset('SiteConfig')->find( { siteid => $site->id, name => 'getclicky' } );
+
# TODO enable_getclicky
if ($getclicky) {
- $data->{getclicky} = $getclicky->value;
+ $data->{getclicky} = $getclicky->value;
}
- my $content_type = request->content_type || params->{content_type} || '';
- if ($content_type =~ /json/ or request->{path} =~ /\.json/) {
- content_type 'text/plain';
- debug('json', $data);
- return to_json $data, { utf8 => 0, convert_blessed => 1, allow_blessed => 1 };
- } else {
- return template $template, $data;
- }
+ my $content_type = request->content_type || params->{content_type} || '';
+ if ( $content_type =~ /json/ or request->{path} =~ /\.json/ ) {
+ content_type 'text/plain';
+ debug( 'json', $data );
+ return to_json $data, { utf8 => 0, convert_blessed => 1, allow_blessed => 1 };
+ } else {
+ return template $template, $data;
+ }
}
sub get_page_data {
- my ($site, $path, $revision) = @_;
+ my ( $site, $path, $revision ) = @_;
- # make it easy to deploy in CGI environment.
- if ($path eq '/index' or $path eq '/index.html') {
- $path = '/';
- }
+ # make it easy to deploy in CGI environment.
+ if ( $path eq '/index' or $path eq '/index.html' ) {
+ $path = '/';
+ }
- my $db = _get_db();
- my $cpage = $db->resultset('Page')->find( {siteid => $site->id, filename => $path} );
- return if not $cpage;
+ my $db = _get_db();
+ my $cpage = $db->resultset('Page')->find( { siteid => $site->id, filename => $path } );
+ return if not $cpage;
- if (not defined $revision) {
- $revision = $cpage->revision;
- }
- my $page = $db->resultset('PageHistory')->find( { siteid => $site->id, pageid => $cpage->id, revision => $revision });
+ if ( not defined $revision ) {
+ $revision = $cpage->revision;
+ }
+ my $page =
+ $db->resultset('PageHistory')->find( { siteid => $site->id, pageid => $cpage->id, revision => $revision } );
- return if not $page; # TODO that's some serious trouble here!
- return {
- title => $page->title,
- body => $page->body,
- author => $page->author->name,
- filename => $page->filename,
- revision => $revision,
- };
+ return if not $page; # TODO that's some serious trouble here!
+ return {
+ title => $page->title,
+ body => $page->body,
+ author => $page->author->name,
+ filename => $page->filename,
+ revision => $revision,
+ };
}
###### routes
get '/history.json' => sub {
- my ($site_name, $site) = _get_site();
- my $path = params->{filename};
- return to_json {error => 'no_site_found' } if not $site;
-
- my $db = _get_db();
-# my $cpage = $db->resultset('Page')->find( {siteid => $site->id, filename => $path} );
-# my @history =
-# die $history;
- my @history = reverse map { {
- revision => $_->revision,
- timestamp => $_->timestamp,
- author => $_->author->name,
- filename => $path,
- } }
- $db->resultset('PageHistory')->search( {siteid => $site->id, filename => $path} ); # sort by revision!?
- return to_json { rows => \@history };
+ my ( $site_name, $site ) = _get_site();
+ my $db = _get_db();
+
+ my $path = params->{filename};
+
+ # my $cpage = $db->resultset('Page')->find( {siteid => $site->id, filename => $path} );
+ # my @history =
+ # die $history;
+ my @history =
+ reverse
+ map { { revision => $_->revision, timestamp => $_->timestamp, author => $_->author->name, filename => $path, } }
+ $db->resultset('PageHistory')->search( { siteid => $site->id, filename => $path } ); # sort by revision!?
+ return to_json { rows => \@history };
};
get '/page.json' => sub {
- my ($site_name, $site) = _get_site();
- my $path = params->{filename};
- return to_json {error => 'no_site_found' } if not $site;
-
- my $revision = params->{revision};
-
- my $data = get_page_data($site, $path, $revision);
- if ($data) {
- return to_json { page => $data };
- } else {
- return to_json { error => 'page_does_not_exist' };
- }
+ my ( $site_name, $site ) = _get_site();
+ my $path = params->{filename};
+
+ my $revision = params->{revision};
+
+ my $data = get_page_data( $site, $path, $revision );
+ if ($data) {
+ return to_json { page => $data };
+ } else {
+ return to_json { error => 'page_does_not_exist', details => "$path revision " . ( $revision || '' ) };
+ }
};
post '/save_page.json' => sub {
- my ($site_name, $site) = _get_site();
-
- return to_json { error => "no_site" } if not $site;
- my $filename = params->{filename};
- return to_json { error => "no_file_supplied" } if not $filename;
-
- return save_page($site->id, {
- create => params->{create},
- editor_title => params->{editor_title},
- editor_body => params->{editor_body},
- author => session->{userid},
- filename => $filename,
- })
+ my ( $site_name, $site ) = _get_site();
+
+ my $filename = params->{filename};
+ return to_json { error => "no_file_supplied" } if not $filename;
+
+ return save_page(
+ $site->id,
+ { create => params->{create},
+ editor_title => params->{editor_title},
+ editor_body => params->{editor_body},
+ author => session->{userid},
+ filename => $filename,
+ }
+ );
};
post '/login.json' => sub {
- my $username = params->{username};
- my $password = params->{password};
-
- return to_json { error => 'missing_username' } if not $username;
- return to_json { error => 'missing_password' } if not $password;
-
- my $db = _get_db();
- my $user = $db->resultset('User')->find( {name => $username});
- return to_json { error => 'no_such_user' } if not $user;
-
- my $sha1 = sha1_base64($password);
- return to_json { error => 'invalid_password' } if $sha1 ne $user->sha1;
-
- return { error => 'not_verified' } if not $user->verified;
-
- session username => $username;
- session userid => $user->id;
- session logged_in => 1;
-
- my $data = { success => 1 };
- include_session($data);
- return to_json $data;
+ my $username = params->{username};
+ my $password = params->{password};
+
+ return to_json { error => 'missing_username' } if not $username;
+ return to_json { error => 'missing_password' } if not $password;
+
+ my $db = _get_db();
+ my $user = $db->resultset('User')->find( { name => $username } );
+ return to_json { error => 'no_such_user' } if not $user;
+
+ my $sha1 = sha1_base64($password);
+ return to_json { error => 'invalid_password' } if $sha1 ne $user->sha1;
+
+ return { error => 'not_verified' } if not $user->verified;
+
+ session username => $username;
+ session userid => $user->id;
+ session logged_in => 1;
+
+ my $data = { success => 1 };
+ include_session($data);
+ return to_json $data;
};
get '/logout.json' => sub {
- session->destroy;
- return to_json {success => 1};
+ session->destroy;
+ return to_json { success => 1 };
};
get '/list_users.json' => sub {
- my $db = _get_db();
- my @users = map { { id => $_->id, name => $_->name } } $db->resultset('User')->all();
- return to_json { users => \@users };
+ my $db = _get_db();
+ my @users = map { { id => $_->id, name => $_->name } } $db->resultset('User')->all();
+ return to_json { users => \@users };
};
any '/needs_login' => sub {
- return render_response 'error', { not_logged_in => 1 };
+ return render_response 'error', { not_logged_in => 1 };
};
any '/needs_login.json' => sub {
- return render_response 'error', { error => 'not_logged_in' };
+ return render_response 'error', { error => 'not_logged_in' };
};
get '/session.json' => sub {
- my $data = {logged_in => 0};
- include_session($data);
- return to_json $data;
+ my ( $site_name, $site ) = _get_site();
+ my $data = {
+ logged_in => 0,
+ data => get_site_config_data(),
+ site => {
+ name => $site_name,
+ id => $site->id,
+ },
+ };
+ include_session($data);
+
+ return to_json $data;
};
get '/get_user.json' => sub {
- my $id = params->{id};
- return to_json { error => 'no_id' } if not defined $id;
- my $db = _get_db();
- my $user = $db->resultset('User')->find( $id );
- return to_josn { error => 'no_such_user' } if not defined $id;
- my @fields = qw(id name email fname lname verified register_ts);
- my %data = map { $_ => $user->$_ } @fields;
- return to_json \%data;
+ my $id = params->{id};
+ return to_json { error => 'no_id' } if not defined $id;
+ my $db = _get_db();
+ my $user = $db->resultset('User')->find($id);
+ return to_josn { error => 'no_such_user' } if not defined $id;
+ my @fields = qw(id name email fname lname verified register_ts);
+ my %data = map { $_ => $user->$_ } @fields;
+ return to_json \%data;
};
post '/add_user.json' => sub {
- my %args;
- foreach my $field ( qw(uname fname lname email pw1 pw2 verify) ) {
- $args{$field} = params->{$field} || '';
- trim($args{$field});
- }
- #return $args{verify};
+ my %args = _clean_params(qw(uname fname lname email pw1 pw2 verify));
- if ($args{pw1} eq '' and $args{pw2} eq '') {
- $args{pw1} = $args{pw2} = String::Random->new->randregex('[a-zA-Z0-9]{10}');
- }
- $args{tos} = 'on'; # TODO not really the right thing, mark in the database that the user was added by the admin
+ #return $args{verify};
- return to_json { error => 'invalid_verify' } if $args{verify} !~ /^(send_email|verified)$/;
+ if ( $args{pw1} eq '' and $args{pw2} eq '' ) {
+ $args{pw1} = $args{pw2} = String::Random->new->randregex('[a-zA-Z0-9]{10}');
+ }
+ $args{tos} = 'on'; # TODO not really the right thing, mark in the database that the user was added by the admin
- my $ret = register_user(%args);
- return to_json { error => $ret } if $ret;
+ return to_json { error => 'invalid_verify' } if $args{verify} !~ /^(send_email|verified)$/;
- return to_json { success => 1 };
+ my $ret = register_user(%args);
+ return to_json { error => $ret } if $ret;
+
+ return to_json { success => 1 };
};
get '/register' => sub {
- render_response 'register';
+ render_response 'register';
};
post '/register' => sub {
- my %args;
- foreach my $field ( qw(uname fname lname email pw1 pw2 verify tos) ) {
- $args{$field} = params->{$field} || '';
- trim($args{$field});
- }
- $args{verify} = 'send_email';
+ my %args = _clean_params(qw(uname fname lname email pw1 pw2 verify tos));
+ $args{verify} = 'send_email';
- my $ret = register_user(%args);
- return render_response 'error', {$ret => 1} if $ret;
+ my $ret = register_user(%args);
+ return render_response 'error', { $ret => 1 } if $ret;
- redirect '/register_done';
+ redirect '/register_done';
};
sub register_user {
- my %args = @_;
- # validate
- $args{email} = lc $args{email};
-
- my $db = _get_db();
- if (length $args{uname} < 2 or $args{uname} =~ /[^\w.-]/) {
- return 'invalid_username';
- }
- my $user = $db->resultset('User')->find( { name => $args{uname} });
- if ($user) {
- return 'username_taken';
- }
- $user = $db->resultset('User')->find( {email => $args{email}});
- if ($user) {
- return 'email_used';
- }
- if (length $args{pw1} < 5) {
- return 'short_password';
- }
- if ($args{pw1} ne $args{pw2}) {
- return 'passwords_dont_match';
- }
- if ($args{tos} ne 'on') {
- return 'no_tos';
- };
-
- # insert new user
- my $time = time;
- my $validation_key = String::Random->new->randregex('[a-zA-Z0-9]{10}') . $time . String::Random->new->randregex('[a-zA-Z0-9]{10}');
- $user = $db->resultset('User')->create({
- name => $args{uname},
- email => $args{email},
- sha1 => sha1_base64($args{pw1}),
- validation_key => $validation_key,
- verified => ($args{verify} eq 'verified' ? 1 : 0),
- register_ts => $time,
- });
-
- if ($args{verify} eq 'send_email') {
- my $template = read_file(path(config->{appdir}, 'views', 'register_verify_mail.tt'));
- if ($user) {
- my $url = 'http://' . request->host . "/finish_registration?uname=$args{uname}&code=$validation_key";
- my $message = ''; # template 'register_verify_mail', { url => $url };
- my $msg = MIME::Lite->new(
- From => 'gabor@szabgab.com',
- To => $args{email},
- Subject => 'Verify your registration to Dwimmer!',
- Data => $message,
- );
- $msg->send;
- }
- } else {
- # set the verified bit?
- }
-
- return;
+ my %args = @_;
+
+ # validate
+ $args{email} = lc $args{email};
+
+ my $db = _get_db();
+ if ( length $args{uname} < 2 or $args{uname} =~ /[^\w.-]/ ) {
+ return 'invalid_username';
+ }
+ my $user = $db->resultset('User')->find( { name => $args{uname} } );
+ if ($user) {
+ return 'username_taken';
+ }
+ $user = $db->resultset('User')->find( { email => $args{email} } );
+ if ($user) {
+ return 'email_used';
+ }
+ if ( length $args{pw1} < 5 ) {
+ return 'short_password';
+ }
+ if ( $args{pw1} ne $args{pw2} ) {
+ return 'passwords_dont_match';
+ }
+ if ( $args{tos} ne 'on' ) {
+ return 'no_tos';
+ }
+
+ # insert new user
+ my $time = time;
+ my $validation_key =
+ String::Random->new->randregex('[a-zA-Z0-9]{10}') . $time . String::Random->new->randregex('[a-zA-Z0-9]{10}');
+ $user = $db->resultset('User')->create(
+ { name => $args{uname},
+ email => $args{email},
+ sha1 => sha1_base64( $args{pw1} ),
+ validation_key => $validation_key,
+ verified => ( $args{verify} eq 'verified' ? 1 : 0 ),
+ register_ts => $time,
+ }
+ );
+
+ if ( $args{verify} eq 'send_email' ) {
+ my $template = read_file( path( config->{appdir}, 'views', 'register_verify_mail.tt' ) );
+ if ($user) {
+ my $url = 'http://' . request->host . "/finish_registration?uname=$args{uname}&code=$validation_key";
+ my $message = ''; # template 'register_verify_mail', { url => $url };
+ my $msg = MIME::Lite->new(
+ From => 'gabor@szabgab.com',
+ To => $args{email},
+ Subject => 'Verify your registration to Dwimmer!',
+ Data => $message,
+ );
+ $msg->send;
+ }
+ } else {
+
+ # set the verified bit?
+ }
+
+ return;
}
get '/get_pages.json' => sub {
- my ($site_name, $site) = _get_site();
- my $db = _get_db();
- my @res = $db->resultset('Page')->search( {siteid => $site->id} );
+ my ( $site_name, $site ) = _get_site();
+ my $db = _get_db();
+
+ my @res = $db->resultset('Page')->search( { siteid => $site->id } );
- my @rows = map { { id => $_->id, filename => $_->filename, title => $_->details->title } } @res;
+ my @rows = map { { id => $_->id, filename => $_->filename, title => $_->details->title } } @res;
- return to_json { rows => \@rows };
+ return to_json { rows => \@rows };
};
post '/create_feed_collector.json' => sub {
- my ($site_name, $site) = _get_site();
- my $db = _get_db();
- my $name = (params->{name} || '');
+ my ( $site_name, $site ) = _get_site();
+ my $db = _get_db();
+
+ my $name = ( params->{name} || '' );
- return to_json {error => 'no_name_given' } if not $name;
+ return to_json { error => 'no_name_given' } if not $name;
- my $time = time;
+ my $time = time;
- my $collector = $db->resultset('FeedCollector')->find( { name => $name } );
- return to_json { error => 'feed_collector_exists' } if $collector;
+ my $collector = $db->resultset('FeedCollector')->find( { name => $name } );
+ return to_json { error => 'feed_collector_exists' } if $collector;
- eval {
- my $collector = $db->resultset('FeedCollector')->create({
- name => $name,
- created_ts => $time,
- owner => session->{userid},
- });
- };
- if ($@) {
- return to_json {error => 'failed' };
- }
+ eval {
+ my $collector = $db->resultset('FeedCollector')->create(
+ { name => $name,
+ created_ts => $time,
+ owner => session->{userid},
+ }
+ );
+ };
- return to_json { success => 1 };
+ if ($@) {
+ return to_json { error => 'failed' };
+ }
+
+ return to_json { success => 1 };
};
get '/feed_collectors.json' => sub {
- my ($site_name, $site) = _get_site();
- my $db = _get_db();
+ my ( $site_name, $site ) = _get_site();
+ my $db = _get_db();
- my @result = map { {
- id => $_->id,
- name => $_->name,
- ownerid => $_->owner->id,
- } } $db->resultset('FeedCollector')->search( { owner => session->{userid} } );
+ my @result =
+ map { { id => $_->id, name => $_->name, ownerid => $_->owner->id, } }
+ $db->resultset('FeedCollector')->search( { owner => session->{userid} } );
- return to_json { rows => \@result };
+ return to_json { rows => \@result };
};
post '/add_feed.json' => sub {
- my ($site_name, $site) = _get_site();
- my $db = _get_db();
-
- my %args;
- foreach my $f (qw(title url feed collector)) {
- $args{$f} = (params->{$f} || '');
- return to_json { error => "missing_$f" } if not $args{$f};
- }
-
- my $collector = $db->resultset('FeedCollector')->find( { id => $args{collector} } );
- return to_json { error => 'invalid_collector_id' } if not $collector;
- # is it owned by the same user?
-
- return to_json { error => 'collector_not_owned_by_user' }
- if $collector->owner->id ne session->{userid};
-
- eval {
- my $feed = $db->resultset('Feed')->create({
- %args,
- collector => session->{userid},
- });
- };
- if ($@) {
- return to_json {error => $@ };
- }
-
- return to_json { success => 1 };
+ my ( $site_name, $site ) = _get_site();
+ my $db = _get_db();
+
+ my %args;
+ foreach my $f (qw(title url feed collector)) {
+ $args{$f} = ( params->{$f} || '' );
+ return to_json { error => "missing_$f" } if not $args{$f};
+ }
+
+ my $collector = $db->resultset('FeedCollector')->find( { id => $args{collector} } );
+ return to_json { error => 'invalid_collector_id' } if not $collector;
+
+ # is it owned by the same user?
+
+ return to_json { error => 'collector_not_owned_by_user' }
+ if $collector->owner->id ne session->{userid};
+
+ eval { my $feed = $db->resultset('Feed')->create( { %args, collector => session->{userid}, } ); };
+ if ($@) {
+ return to_json { error => $@ };
+ }
+
+ return to_json { success => 1 };
};
get '/feeds.json' => sub {
- my ($site_name, $site) = _get_site();
- my $db = _get_db();
-
- my %args;
- foreach my $f (qw(collector)) {
- $args{$f} = (params->{$f} || '');
- return to_json { error => "missing_$f" } if not $args{$f};
- }
- # is it owned by the same user?
-
- my @result = map { {
- id => $_->id,
- title => $_->title,
- url => $_->url,
- feed => $_->feed,
- } } $db->resultset('Feed')->search( { collector => $args{collector} } );
-
- return to_json { rows => \@result };
+ my ( $site_name, $site ) = _get_site();
+ my $db = _get_db();
+
+ my %args;
+ foreach my $f (qw(collector)) {
+ $args{$f} = ( params->{$f} || '' );
+ return to_json { error => "missing_$f" } if not $args{$f};
+ }
+
+ # is it owned by the same user?
+
+ my @result =
+ map { { id => $_->id, title => $_->title, url => $_->url, feed => $_->feed, } }
+ $db->resultset('Feed')->search( { collector => $args{collector} } );
+
+ return to_json { rows => \@result };
};
post '/create_list.json' => sub {
- my ($site_name, $site) = _get_site();
- return to_json {error => 'no_site_found' } if not $site;
-
- my $title = params->{'title'} || '';
- trim($title);
- return to_json { 'error' => 'no_title' } if not $title;
-
- my $name = params->{'name'} || '';
- trim($name);
- return to_json { 'error' => 'no_name' } if not $name;
- if ($name !~ /^[a-z_]{4,}$/) {
- return to_json { 'error' => 'invalid_list_name' };
- }
-
- my $from_address = params->{'from_address'} || '';
- trim($from_address);
- return to_json { 'error' => 'no_from_address' } if not $from_address;
-
- my %data;
- foreach my $f (qw(response_page validation_page validation_response_page)) {
- $data{$f} = params->{$f} || '';
- }
- my $validate_template = params->{'validate_template'} || '';
- my $confirm_template = params->{'confirm_template'} || '';
-
- my $db = _get_db();
- my $list = $db->resultset('MailingList')->create({
- owner => session->{userid},
- title => $title,
- name => $name,
- from_address => $from_address,
- %data,
- validate_template => $validate_template,
- confirm_template => $confirm_template,
- });
- return to_json { success => 1, listid => $list->id };
+ my ( $site_name, $site ) = _get_site();
+
+ my %params = _clean_params(
+ qw(title name from_address
+ response_page validation_page validation_response_page)
+ );
+
+ return to_json { 'error' => 'no_title' } if not $params{title};
+ return to_json { 'error' => 'no_name' } if not $params{name};
+ if ( $params{name} !~ /^[a-z_]{4,}$/ ) {
+ return to_json { 'error' => 'invalid_list_name' };
+ }
+ return to_json { 'error' => 'no_from_address' } if not $params{from_address};
+
+ my $validate_template = params->{'validate_template'} || '';
+ my $confirm_template = params->{'confirm_template'} || '';
+
+ my $db = _get_db();
+ my $list = $db->resultset('MailingList')->create(
+ { owner => session->{userid},
+ %params,
+ validate_template => $validate_template,
+ confirm_template => $confirm_template,
+ }
+ );
+ return to_json { success => 1, listid => $list->id };
};
get '/fetch_lists.json' => sub {
- my ($site_name, $site) = _get_site();
- return to_json {error => 'no_site_found' } if not $site;
- my $db = _get_db();
- my @list = map { {listid => $_->id, owner => $_->owner->id, title => $_->title, name => $_->name} } $db->resultset('MailingList')->all();
- return to_json {success => 1, lists => \@list};
+ my ( $site_name, $site ) = _get_site();
+
+ my $db = _get_db();
+ my @list =
+ map { { listid => $_->id, owner => $_->owner->id, title => $_->title, name => $_->name } }
+ $db->resultset('MailingList')->all();
+ return to_json { success => 1, lists => \@list };
};
-post '/register_email' => \&_register_email;
-get '/register_email.json' => \&_register_email;
+post '/register_email' => \&_register_email;
+get '/register_email.json' => \&_register_email;
sub _register_email {
- my ($site_name, $site) = _get_site();
- return to_json {error => 'no_site_found' } if not $site;
-
- # check e-mail
- my $email = lc( params->{'email'} || '' );
- trim($email);
- return render_response 'error', {'no_email' => 1} if not $email;
-
- if (not Email::Valid->address($email)) {
- return render_response 'error', {'invalid_email' => 1};
- }
-
- # check list
- my $listid = params->{listid} || '';
- trim($listid);
- return render_response 'error', {'no_listid' => 1} if not $listid;
-
- my $db = _get_db();
- my $list = $db->resultset('MailingList')->find( { id => $listid } );
- return render_response 'error', {'no_such_list' => 1} if not $list;
-
- # TODO: change schema
- #return render_response 'error', {'list_not_open' => 1} if not $list->open;
-
- my $time = time;
- my $validation_code = String::Random->new->randregex('[a-zA-Z0-9]{10}') . $time . String::Random->new->randregex('[a-zA-Z0-9]{10}');
- my $url = 'http://' . request->host . "/_dwimmer/validate_email?listid=$listid&email=$email&code=$validation_code";
-
- # add member (TODO what if the e-mail is already listed in the same list)
- eval {
- my $user = $db->resultset('MailingListMember')->create({
- listid => $listid,
- email => $email,
- validation_code => $validation_code,
- register_ts => $time,
- approved => 0,
- });
-
- my $subject = $list->title . " registration - email validation";
- my $data = $list->validate_template;
- $data =~ s/<% url %>/$url/g;
- my $msg = MIME::Lite->new(
- From => $list->from_address,
- To => $email,
- Subject => $subject,
- Data => $data,
- );
- $msg->send;
- };
- if ($@) {
- die "ERROR while trying to register ($email) $@";
- return render_response 'error', {'internal_error_when_subscribing' => 1};
- }
-
- if (request->{path} =~ /\.json/) {
- return to_json { success => 1 };
- }
-# return $list->response_page;
-# die $list->response_page;
- redirect $list->response_page;
-# return render_response $list->response_page, { 'success' => 1 };
+ my ( $site_name, $site ) = _get_site();
+
+ # check e-mail
+ my %params = _clean_params(qw(email listid));
+ $params{email} = lc $params{email};
+ return render_response 'error', { 'no_email' => 1 } if not $params{email};
+ return render_response 'error', { 'invalid_email' => 1 }
+ if not Email::Valid->address( $params{email} );
+
+ # check list
+ return render_response 'error', { 'no_listid' => 1 } if not $params{listid};
+
+ my $db = _get_db();
+ my $list = $db->resultset('MailingList')->find( { id => $params{listid} } );
+ return render_response 'error', { 'no_such_list' => 1 } if not $list;
+
+ # TODO: change schema
+ #return render_response 'error', {'list_not_open' => 1} if not $list->open;
+
+ my $time = time;
+ my $validation_code =
+ String::Random->new->randregex('[a-zA-Z0-9]{10}') . $time . String::Random->new->randregex('[a-zA-Z0-9]{10}');
+ my $url =
+ 'http://'
+ . request->host
+ . "/_dwimmer/validate_email?listid=$params{listid}&email=$params{email}&code=$validation_code";
+
+ my $same_email = $db->resultset('MailingListMember')->find(
+ { listid => $params{listid},
+ email => $params{email},
+ }
+ );
+ return render_response 'error', { 'email_already_registered' => 1 } if $same_email;
+
+ # TODO: send diffrent error if it was already verified and different if it has not been verified yet
+
+ # add member
+ eval {
+ my $user = $db->resultset('MailingListMember')->create(
+ { listid => $params{listid},
+ email => $params{email},
+ validation_code => $validation_code,
+ register_ts => $time,
+ approved => 0,
+ }
+ );
+
+ my $subject = $list->title . " registration - email validation";
+ my $data = $list->validate_template;
+ $data =~ s/<% url %>/$url/g;
+ my $msg = MIME::Lite->new(
+ From => $list->from_address,
+ To => $params{email},
+ Subject => $subject,
+ Data => $data,
+ );
+ $msg->send;
+ };
+ if ($@) {
+ die "ERROR while trying to register ($params{email}) $@";
+ return render_response 'error', { 'internal_error_when_subscribing' => 1 };
+ }
+
+ if ( request->{path} =~ /\.json/ ) {
+ return to_json { success => 1 };
+ }
+
+ # return $list->response_page;
+ # die $list->response_page;
+ redirect $list->response_page;
+
+ # return render_response $list->response_page, { 'success' => 1 };
}
get '/validate_email' => \&_validate_email;
get '/validate_email.json' => \&_validate_email;
sub _validate_email {
- my ($site_name, $site) = _get_site();
- return to_json {error => 'no_site_found' } if not $site;
-
- my $code = params->{'code'} || '';
- trim($code);
- return to_json { 'error' => 'no_confirmation_code' } if not $code;
-
- my $email = lc( params->{'email'} || '' );
- trim($email);
- return render_response 'error', {'no_email' => 1} if not $email;
-
- my $listid = params->{listid} || '';
- trim($listid);
- return render_response 'error', {'no_listid' => 1} if not $listid;
-
- my $db = _get_db();
- my $list = $db->resultset('MailingList')->find( { id => $listid } );
- eval {
- my $user = $db->resultset('MailingListMember')->find( {validation_code => $code, email => $email, listid => $listid} );
- if (not $user) {
- return to_json { 'error' => 'invalid_confirmation_code' };
- }
- $user->approved(1);
- $user->update;
-
- my $subject = $list->title . " - Thank you for subscribing";
- my $data = $list->confirm_template;
- #$data =~ s/<% url %>/$url/g;
- my $msg = MIME::Lite->new(
- From => $list->from_address,
- To => $email,
- Subject => $subject,
- Data => $data,
- );
- $msg->send;
-
- };
- if ($@) {
- return render_response 'error', {'internal_error_when_confirming' => 1};
- }
-
- if (request->{path} =~ /\.json/) {
- return to_json { success => 1 };
- }
- #die $list->validation_response_page;
- redirect $list->validation_response_page;
-# return render_response $list->validation_response_page, { 'success' => 1 };
-};
+ my ( $site_name, $site ) = _get_site();
+
+ my %params = _clean_params(qw(code email listid));
+ $params{email} = lc $params{email};
+ return to_json { 'error' => 'no_confirmation_code' } if not $params{code};
+ return render_response 'error', { 'no_email' => 1 } if not $params{email};
+ return render_response 'error', { 'no_listid' => 1 } if not $params{listid};
+
+ my $db = _get_db();
+ my $list = $db->resultset('MailingList')->find( { id => $params{listid} } );
+ eval {
+ my $user =
+ $db->resultset('MailingListMember')
+ ->find( { validation_code => $params{code}, email => $params{email}, listid => $params{listid} } );
+ if ( not $user ) {
+ return to_json { 'error' => 'invalid_confirmation_code' };
+ }
+ $user->approved(1);
+ $user->update;
+
+ my $subject = $list->title . " - Thank you for subscribing";
+ my $data = $list->confirm_template;
+
+ #$data =~ s/<% url %>/$url/g;
+ my $msg = MIME::Lite->new(
+ From => $list->from_address,
+ To => $params{email},
+ Subject => $subject,
+ Data => $data,
+ );
+ $msg->send;
+
+ };
+ if ($@) {
+ return render_response 'error', { 'internal_error_when_confirming' => 1 };
+ }
+
+ if ( request->{path} =~ /\.json/ ) {
+ return to_json { success => 1 };
+ }
+
+ #die $list->validation_response_page;
+ redirect $list->validation_response_page;
+
+ # return render_response $list->validation_response_page, { 'success' => 1 };
+}
get '/list_members.json' => sub {
- my $listid = params->{listid} || '';
- trim($listid);
- return render_response 'error', {'no_listid' => 1} if not $listid;
- my $db = _get_db();
- my @members = map { { id => $_->id, email => $_->email, approved => $_->approved } }
- $db->resultset('MailingListMember')->search( { listid => $listid } );
- return to_json { members => \@members };
+ my %params = _clean_params(qw(listid));
+ return render_response 'error', { 'no_listid' => 1 } if not $params{listid};
+
+ my $db = _get_db();
+ my @members =
+ map { { id => $_->id, email => $_->email, approved => $_->approved } }
+ $db->resultset('MailingListMember')->search( \%params );
+ return to_json { members => \@members };
};
post '/create_site.json' => sub {
- my %args;
- foreach my $field ( qw(name) ) {
- $args{$field} = params->{$field} || '';
- trim($args{$field});
- }
+ my %params = _clean_params(qw(name));
- return to_json {error => 'missing_name' } if not $args{name};
+ return to_json { error => 'missing_name' } if not $params{name};
- create_site($args{name}, $args{name}, session->{userid});
+ create_site( $params{name}, $params{name}, session->{userid} );
- return to_json { success => 1 };
+ return to_json { success => 1 };
};
get '/sites.json' => sub {
- my $db = _get_db();
- my @rows = map { {id => $_->id, name => $_->name, owner => $_->owner->id} } $db->resultset('Site')->all;
- return to_json { rows => \@rows };
+ my $db = _get_db();
+ my @rows = map { { id => $_->id, name => $_->name, owner => $_->owner->id } } $db->resultset('Site')->all;
+ return to_json { rows => \@rows };
};
get '/site_config.json' => sub {
-
- my %args;
- $args{siteid} = params->{siteid} || '';
- trim($args{siteid});
- return render_response 'error', {'no_siteid' => 1} if not $args{siteid};
-
- my $db = _get_db();
- #my @rows = map { {siteid => $_->siteid, name => $_->name, value => $_->value} }
- my %data = map { $_->name => $_->value } $db->resultset('SiteConfig')->search( \%args );
- #return to_json { rows => \@rows };
- return to_json { data => \%data };
+ my $data = get_site_config_data();
+ return to_json { data => $data };
};
+
+sub get_site_config_data {
+
+ my %params = _clean_params(qw(siteid));
+
+ # default to current site
+ if ( not $params{siteid} ) {
+ my ( $site_name, $site ) = _get_site();
+ $params{siteid} = $site->id;
+ }
+
+ #return render_response 'error', { 'no_siteid' => 1 } if not $params{siteid};
+
+ my $db = _get_db();
+
+ my %data = map { $_->name => $_->value } $db->resultset('SiteConfig')->search( \%params );
+
+ $data{page_size} ||= 10; # default
+
+ return \%data;
+}
+
sub _clean_params {
my @fields = @_;
@@ -621,7 +634,7 @@ sub _clean_params {
foreach my $field (@fields) {
$args{$field} = params->{$field};
$args{$field} = '' if not defined $args{$field};
- trim($args{$field});
+ trim( $args{$field} );
}
return %args;
@@ -630,49 +643,71 @@ sub _clean_params {
# TODO test this route from the client!
post '/save_site_config.json' => sub {
my %args = _clean_params(qw(siteid section));
- return to_json { error => 'no_siteid' } if not $args{siteid};
+ return to_json { error => 'no_siteid' } if not $args{siteid};
return to_json { error => 'no_section' } if not $args{section};
my %params;
- if ($args{section} eq 'google_analytics') {
+ if ( $args{section} eq 'google_analytics' ) {
%params = _clean_params(qw(google_analytics enable_google_analytics));
- } elsif ($args{section} eq 'getclicky') {
+ } elsif ( $args{section} eq 'getclicky' ) {
%params = _clean_params(qw(getclicky enable_getclicky));
+ } elsif ( $args{section} eq 'general' ) {
+ %params = _clean_params(qw(page_size no_guest_bar show_experimental_features));
} else {
return to_json { error => 'invalid_section' };
}
- foreach my $field (keys %params) {
+ $params{no_guest_bar} = $params{no_guest_bar} eq 'on' ? 1 : 0;
+ $params{show_experimental_features} = $params{show_experimental_features} eq 'on' ? 1 : 0;
+ foreach my $field ( keys %params ) {
_set_site_config( siteid => $args{siteid}, name => $field, value => $params{$field} );
}
- return to_json { success => 1 };
+ return to_json { success => 1 };
};
post '/set_site_config.json' => sub {
- my %args;
+ my %params = _clean_params(qw(siteid name value));
+ return render_response 'error', { 'no_siteid' => 1 } if not $params{siteid};
+ return render_response 'error', { 'no_name' => 1 } if not $params{name};
+ _set_site_config(%params);
- foreach my $field (qw(siteid name value)) {
- $args{$field} = params->{$field};
- $args{$field} = '' if not defined $args{$field};
- trim($args{$field});
- }
- return render_response 'error', {'no_siteid' => 1} if not $args{siteid};
- return render_response 'error', {'no_name' => 1} if not $args{name};
- _set_site_config( %args );
+ return to_json { success => 1 };
+};
+
+post '/change_password.json' => sub {
+ my %params = _clean_params(qw(new_password old_password));
+ return render_response 'error', { 'no_new_password' => 1 } if not $params{new_password};
+ return render_response 'error', { 'no_old_password' => 1 } if not $params{old_password};
+
+ # TODO shall we check some password requirements?
+
+ my $old_sha1 = sha1_base64( $params{old_password} );
+ my $new_sha1 = sha1_base64( $params{new_password} );
+
+ my $db = _get_db();
+ my $user = $db->resultset('User')->find( { id => session->{userid} } );
+
+ return render_response 'error', { 'no_user_found' => 1 } if not $user;
+
+ return render_response 'error', { 'no_invalid_old_password' => 1 }
+ if $user->sha1 ne $old_sha1;
+
+ $user->sha1($new_sha1);
+ $user->update;
- return to_json { success => 1 };
+ return to_json { success => 1 };
};
sub _set_site_config {
my %args = @_;
- my $db = _get_db();
+ my $db = _get_db();
my $option = $db->resultset('SiteConfig')->find( { siteid => $args{siteid}, name => $args{name} } );
if ($option) {
$option->value( $args{value} );
$option->update;
} else {
- my $option = $db->resultset('SiteConfig')->create( \%args );
+ my $option = $db->resultset('SiteConfig')->create( \%args );
}
}
View
25 lib/Dwimmer/Client.pm
@@ -4,18 +4,18 @@ use Moose;
use WWW::Mechanize;
use JSON qw(from_json);
-has host => (is => 'ro', isa => 'Str', required => 1);
-has mech => (is => 'rw', isa => 'WWW::Mechanize', default => sub { WWW::Mechanize->new } );
+has host => ( is => 'ro', isa => 'Str', required => 1 );
+has mech => ( is => 'rw', isa => 'WWW::Mechanize', default => sub { WWW::Mechanize->new } );
-our $VERSION = '0.20';
+our $VERSION = '0.21';
# get_user parameters can be id => 1
sub save_page {
- my ($self, %args) = @_;
+ my ( $self, %args ) = @_;
my $m = $self->mech;
- $args{editor_body} = delete $args{body};
+ $args{editor_body} = delete $args{body};
$args{editor_title} = delete $args{title};
$m->post( $self->host . "/_dwimmer/save_page.json", \%args );
return from_json $m->content;
@@ -42,6 +42,7 @@ my %GET = map { $_ => $_ } qw(
my %POST = map { $_ => $_ } qw(
add_feed
add_user
+ change_password
create_feed_collector
create_list
create_site
@@ -51,19 +52,21 @@ my %POST = map { $_ => $_ } qw(
AUTOLOAD {
our $AUTOLOAD;
- (my $sub = $AUTOLOAD) =~ s/^Dwimmer::Client:://;
- my ($self, %attr) = @_;
+ ( my $sub = $AUTOLOAD ) =~ s/^Dwimmer::Client:://;
+ my ( $self, %attr ) = @_;
my $m = $self->mech;
- if ($GET{$sub}) {
- my $params = join "&", map { "$_=$attr{$_}" } keys %attr;
+ if ( $GET{$sub} ) {
+ my $params = join "&", map {"$_=$attr{$_}"} keys %attr;
my $url = $self->host . "/_dwimmer/$GET{$sub}.json?$params";
+
#warn $url;
$m->get($url);
- } elsif ($POST{$sub}) {
+ } elsif ( $POST{$sub} ) {
my $url = $self->host . "/_dwimmer/$POST{$sub}.json";
+
#warn $url;
- $m->post($url, \%attr);
+ $m->post( $url, \%attr );
} else {
die "Could not locate method '$sub'\n";
}
View
14 lib/Dwimmer/DB/Result/Config.pm
@@ -40,15 +40,15 @@ __PACKAGE__->table("config");
=cut
__PACKAGE__->add_columns(
- "id",
- { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
- "name",
- { data_type => "varchar", is_nullable => 0, size => 30 },
- "value",
- { data_type => "varchar", is_nullable => 1, size => 100 },
+ "id",
+ { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
+ "name",
+ { data_type => "varchar", is_nullable => 0, size => 30 },
+ "value",
+ { data_type => "varchar", is_nullable => 1, size => 100 },
);
__PACKAGE__->set_primary_key("id");
-__PACKAGE__->add_unique_constraint("name_unique", ["name"]);
+__PACKAGE__->add_unique_constraint( "name_unique", ["name"] );
# Created by DBIx::Class::Schema::Loader v0.07010 @ 2011-07-27 18:33:50
View
37 lib/Dwimmer/DB/Result/Feed.pm
@@ -52,16 +52,16 @@ __PACKAGE__->table("feeds");
=cut
__PACKAGE__->add_columns(
- "id",
- { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
- "collector",
- { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
- "title",
- { data_type => "varchar", is_nullable => 1, size => 100 },
- "url",
- { data_type => "varchar", is_nullable => 1, size => 255 },
- "feed",
- { data_type => "varchar", is_nullable => 1, size => 255 },
+ "id",
+ { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
+ "collector",
+ { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
+ "title",
+ { data_type => "varchar", is_nullable => 1, size => 100 },
+ "url",
+ { data_type => "varchar", is_nullable => 1, size => 255 },
+ "feed",
+ { data_type => "varchar", is_nullable => 1, size => 255 },
);
__PACKAGE__->set_primary_key("id");
@@ -76,15 +76,14 @@ Related object: L<Dwimmer::DB::Result::FeedCollector>
=cut
__PACKAGE__->belongs_to(
- "collector",
- "Dwimmer::DB::Result::FeedCollector",
- { id => "collector" },
- {
- is_deferrable => 1,
- join_type => "LEFT",
- on_delete => "CASCADE",
- on_update => "CASCADE",
- },
+ "collector",
+ "Dwimmer::DB::Result::FeedCollector",
+ { id => "collector" },
+ { is_deferrable => 1,
+ join_type => "LEFT",
+ on_delete => "CASCADE",
+ on_update => "CASCADE",
+ },
);
View
34 lib/Dwimmer/DB/Result/FeedCollector.pm
@@ -45,17 +45,17 @@ __PACKAGE__->table("feed_collector");
=cut
__PACKAGE__->add_columns(
- "id",
- { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
- "name",
- { data_type => "varchar", is_nullable => 0, size => 100 },
- "owner",
- { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
- "created_ts",
- { data_type => "integer", is_nullable => 0 },
+ "id",
+ { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
+ "name",
+ { data_type => "varchar", is_nullable => 0, size => 100 },
+ "owner",
+ { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+ "created_ts",
+ { data_type => "integer", is_nullable => 0 },
);
__PACKAGE__->set_primary_key("id");
-__PACKAGE__->add_unique_constraint("name_unique", ["name"]);
+__PACKAGE__->add_unique_constraint( "name_unique", ["name"] );
=head1 RELATIONS
@@ -68,10 +68,10 @@ Related object: L<Dwimmer::DB::Result::User>
=cut
__PACKAGE__->belongs_to(
- "owner",
- "Dwimmer::DB::Result::User",
- { id => "owner" },
- { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+ "owner",
+ "Dwimmer::DB::Result::User",
+ { id => "owner" },
+ { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
=head2 feeds
@@ -83,10 +83,10 @@ Related object: L<Dwimmer::DB::Result::Feed>
=cut
__PACKAGE__->has_many(
- "feeds",
- "Dwimmer::DB::Result::Feed",
- { "foreign.collector" => "self.id" },
- { cascade_copy => 0, cascade_delete => 0 },
+ "feeds",
+ "Dwimmer::DB::Result::Feed",
+ { "foreign.collector" => "self.id" },
+ { cascade_copy => 0, cascade_delete => 0 },
);
View
50 lib/Dwimmer/DB/Result/MailingList.pm
@@ -80,29 +80,29 @@ __PACKAGE__->table("mailing_list");
=cut
__PACKAGE__->add_columns(
- "id",
- { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
- "name",
- { data_type => "varchar", is_nullable => 0, size => 100 },
- "title",
- { data_type => "varchar", is_nullable => 0, size => 100 },
- "owner",
- { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
- "from_address",
- { data_type => "varchar", is_nullable => 0, size => 100 },
- "response_page",
- { data_type => "varchar", is_nullable => 1, size => 50 },
- "validation_page",
- { data_type => "varchar", is_nullable => 1, size => 50 },
- "validation_response_page",
- { data_type => "varchar", is_nullable => 1, size => 50 },
- "validate_template",
- { data_type => "blob", is_nullable => 1 },
- "confirm_template",
- { data_type => "blob", is_nullable => 1 },
+ "id",
+ { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
+ "name",
+ { data_type => "varchar", is_nullable => 0, size => 100 },
+ "title",
+ { data_type => "varchar", is_nullable => 0, size => 100 },
+ "owner",
+ { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+ "from_address",
+ { data_type => "varchar", is_nullable => 0, size => 100 },
+ "response_page",
+ { data_type => "varchar", is_nullable => 1, size => 50 },
+ "validation_page",
+ { data_type => "varchar", is_nullable => 1, size => 50 },
+ "validation_response_page",
+ { data_type => "varchar", is_nullable => 1, size => 50 },
+ "validate_template",
+ { data_type => "blob", is_nullable => 1 },
+ "confirm_template",
+ { data_type => "blob", is_nullable => 1 },
);
__PACKAGE__->set_primary_key("id");
-__PACKAGE__->add_unique_constraint("name_unique", ["name"]);
+__PACKAGE__->add_unique_constraint( "name_unique", ["name"] );
=head1 RELATIONS
@@ -115,10 +115,10 @@ Related object: L<Dwimmer::DB::Result::User>
=cut
__PACKAGE__->belongs_to(
- "owner",
- "Dwimmer::DB::Result::User",
- { id => "owner" },
- { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+ "owner",
+ "Dwimmer::DB::Result::User",
+ { id => "owner" },
+ { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
View
38 lib/Dwimmer/DB/Result/MailingListMember.pm
@@ -62,23 +62,23 @@ __PACKAGE__->table("mailing_list_member");
=cut
__PACKAGE__->add_columns(
- "id",
- { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
- "listid",
- { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
- "email",
- { data_type => "varchar", is_nullable => 0, size => 100 },
- "validation_code",
- { data_type => "varchar", is_nullable => 1, size => 255 },
- "approved",
- { data_type => "bool", is_nullable => 1 },
- "register_ts",
- { data_type => "integer", is_nullable => 1 },
- "name",
- { data_type => "varchar", is_nullable => 1, size => 100 },
+ "id",
+ { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
+ "listid",
+ { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+ "email",
+ { data_type => "varchar", is_nullable => 0, size => 100 },
+ "validation_code",
+ { data_type => "varchar", is_nullable => 1, size => 255 },
+ "approved",
+ { data_type => "bool", is_nullable => 1 },
+ "register_ts",
+ { data_type => "integer", is_nullable => 1 },
+ "name",
+ { data_type => "varchar", is_nullable => 1, size => 100 },
);
__PACKAGE__->set_primary_key("id");
-__PACKAGE__->add_unique_constraint("validation_code_unique", ["validation_code"]);
+__PACKAGE__->add_unique_constraint( "validation_code_unique", ["validation_code"] );
=head1 RELATIONS
@@ -91,10 +91,10 @@ Related object: L<Dwimmer::DB::Result::User>
=cut
__PACKAGE__->belongs_to(
- "listid",
- "Dwimmer::DB::Result::User",
- { id => "listid" },
- { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+ "listid",
+ "Dwimmer::DB::Result::User",
+ { id => "listid" },
+ { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
);
View
44 lib/Dwimmer/DB/Result/Page.pm
@@ -51,16 +51,16 @@ __PACKAGE__->table("page");
=cut
__PACKAGE__->add_columns(
- "id",
- { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
- "revision",
- { data_type => "integer", is_nullable => 0 },
- "siteid",
- { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
- "filename",
- { data_type => "varchar", is_nullable => 0, size => 255 },
- "redirect",
- { data_type => "varchar", is_nullable => 1, size => 255 },
+ "id",
+ { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
+ "revision",
+ { data_type => "integer", is_nullable => 0 },
+ "siteid",
+ { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+ "filename",
+ { data_type => "varchar", is_nullable => 0, size => 255 },
+ "redirect",
+ { data_type => "varchar", is_nullable => 1, size => 255 },
);
__PACKAGE__->set_primary_key("id");
@@ -75,10 +75,10 @@ Related object: L<Dwimmer::DB::Result::Site>
=cut
__PACKAGE__->belongs_to(
- "siteid",
- "Dwimmer::DB::Result::Site",
- { id => "siteid" },