From e2cc5061d45adf82ce63eaf40972ea29d86a3486 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Fri, 5 Jul 2019 18:01:37 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=97=84=20Create=20DB=20abstraction=20laye?= =?UTF-8?q?r=20for=20invitations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/Lufi/DB/Invitation.pm | 340 +++++++++++++++++++++++++++++++ lib/Lufi/DB/Invitation/Mysql.pm | 13 ++ lib/Lufi/DB/Invitation/Pg.pm | 13 ++ lib/Lufi/DB/Invitation/SQLite.pm | 14 ++ 4 files changed, 380 insertions(+) create mode 100644 lib/Lufi/DB/Invitation.pm create mode 100644 lib/Lufi/DB/Invitation/Mysql.pm create mode 100644 lib/Lufi/DB/Invitation/Pg.pm create mode 100644 lib/Lufi/DB/Invitation/SQLite.pm diff --git a/lib/Lufi/DB/Invitation.pm b/lib/Lufi/DB/Invitation.pm new file mode 100644 index 0000000..a09eb99 --- /dev/null +++ b/lib/Lufi/DB/Invitation.pm @@ -0,0 +1,340 @@ +# vim:set sw=4 ts=4 sts=4 ft=perl expandtab: +package Lufi::DB::Invitation; +use Mojo::Base -base; +use Mojo::File; +use Mojo::Collection 'c'; + +has 'token'; +has 'ldap_user'; +has 'ldap_user_mail'; +has 'guest_mail'; +has 'created_at' => sub { + return time; +}; +has 'expire_at'; +has 'files_sent_at'; +has 'expend_expire_at'; +has 'files'; +has 'show_in_list' => 1; +has 'deleted' => 0; +has 'record' => 0; +has 'app'; + +=head1 NAME + +Lufi::DB::Invitation - DB abstraction layer for Lufi invitations + +=head1 Contributing + +When creating a new database accessor, make sure that it provides the following subroutines. +After that, modify this file and modify the C subroutine to allow to use your accessor. + +Have a look at Lufi::DB::Invitation::SQLite's code: it's simple and may be more understandable that this doc. + +=head1 Attributes + +=over 1 + +=item B : string, invitation token + +=item B : string, the user who created the invitation + +=item B : string, the email of the user who created the invitation + +=item B : string, the email of the guest + +=item B : unix timestamp + +=item B : unix timestamp + +=item B : unix timestamp + +=item B : integer, "error" delay, in minutes + +=item B : string, optional, list of files sent by the guest + +=item B : boolean, if the ldap user want to see the invitation in his/her invitations list + +=item B : boolean + +=item B : a Mojolicious object + +=back + +=head1 Sub routines + +=head2 new + +=over 1 + +=item B : C<$c = Lufi::DB::Invitation-Enew(app =E $self);> + +=item B : any of the attribute above + +=item B : construct a new db accessor object. If the C attribute is provided, it have to load the informations from the database. + +=item B : the db accessor object + +=item B : the app argument is used by Lufi::DB::Invitation to choose which db accessor will be used, you don't need to use it in new(), but you can use it to access helpers or configuration settings in the other subroutines + +=back + +=cut + +sub new { + my $c = shift; + + $c = $c->SUPER::new(@_); + + if (ref($c) eq 'Lufi::DB::Invitation') { + my $dbtype = $c->app->config('dbtype'); + if ($dbtype eq 'sqlite') { + use Lufi::DB::Invitation::SQLite; + $c = Lufi::DB::Invitation::SQLite->new(@_); + } elsif ($dbtype eq 'postgresql') { + use Lufi::DB::Invitation::Pg; + $c = Lufi::DB::Invitation::Pg->new(@_); + } elsif ($dbtype eq 'mysql') { + use Lufi::DB::Invitation::Mysql; + $c = Lufi::DB::Invitation::Mysql->new(@_); + } + } + + return $c; +} + +sub to_hash { + my $c = shift; + + return { + token => $c->token, + ldap_user => $c->ldap_user, + ldap_user_mail => $c->ldap_user_mail, + guest_mail => $c->guest_mail, + created_at => $c->created_at, + expire_at => $c->expire_at, + files_sent_at => $c->files_sent_at, + expend_expire_at => $c->expend_expire_at, + files => $c->files, + show_in_list => $c->show_in_list, + deleted => $c->deleted + }; +} + +=head2 delete + +=over 1 + +=item B : C<$c-Edelete> + +=item B : none + +=item B : set the C flag to true + +=item B : the db accessor object + +=back + +=cut + +sub delete { + my $c = shift; + + $c->deleted(1); + + $c->write; + + return $c; +} + +=head2 hide + +=over 1 + +=item B : C<$c-Ehide> + +=item B : none + +=item B : set the C flag to false + +=item B : the db accessor object + +=back + +=cut + +sub hide { + my $c = shift; + + $c->show_in_list(0); + + $c->write; + + return $c; +} + +=head2 show + +=over 1 + +=item B : C<$c-Eshow> + +=item B : none + +=item B : set the C flag to true + +=item B : the db accessor object + +=back + +=cut + +sub show { + my $c = shift; + + $c->show_in_list(1); + + $c->write; + + return $c; +} + +=head2 write + +=over 1 + +=item B : C<$c-Ewrite> + +=item B : none + +=item B : create or update a record in the database, with the values of the object's attributes + +=item B : the db accessor object + +=back + +=cut + +sub write { + my $c = shift; + + if ($c->record) { + $c->app->dbi->db->update('invitations', $c->to_hash, { token => $c->token }); + } else { + $c->app->dbi->db->insert('invitations', $c->to_hash); + $c->record(1); + } + + return $c; +} + +=head2 from_token + +=over 1 + +=item B : C<$c-Efrom_token($token)> + +=item B : string + +=item B : find an invitation in the database from its token attribute + +=item B : a db accessor object + +=back + +=cut + +sub from_token { + my $c = shift; + my $token = shift; + + my $r = $c->app->dbi->db->select('invitations', undef, { token => $token })->hashes; + + if ($r->size) { + return $c->_slurp($r->first)->record(1); + } else { + return undef; + } +} + +=head2 is_token_used + +=over 1 + +=item B : C<$c-Edoes_token_exists($token)> + +=item B : string + +=item B : tells if a token is already used. If not, insert it in database to reserve it + +=item B : a boolean + +=back + +=cut + +sub is_token_used { + my $c = shift; + my $token = shift; + + my $r = $c->app->dbi->db->select('invitations', ['token'], { token => $token })->hashes; + + if ($r->size) { + return 1; + } else { + $c->app->dbi->db->insert('invitations', { token => $token }); + return 0; + } +} + +=head2 _slurp + +=over 1 + +=item B : C<$c-E_slurp> + +=item B : none + +=item B : put a database record's columns into the Lufi::DB::Invitation object's attributes + +=item B : the Lufi::DB::Invitation object + +=back + +=cut + +sub _slurp { + my $c = shift; + my $r = shift; + + my $invitation; + if (defined $r) { + $invitation = $r; + } else { + my $invitations = $c->app->dbi->db->select('invitations', undef, { token => $c->token })->hashes; + + if ($invitations->size) { + $invitation = $invitations->first; + } + } + + if ($invitation) { + $c->token( $invitation->{token} ); + $c->ldap_user( $invitation->{ldap_user} ); + $c->ldap_user_mail( $invitation->{ldap_user_mail} ); + $c->guest_mail( $invitation->{guest_mail} ); + $c->created_at( $invitation->{created_at} ); + $c->expire_at( $invitation->{expire_at} ); + $c->files_sent_at( $invitation->{files_sent_at} ); + $c->expend_expire_at($invitation->{expend_expire_at}); + $c->files( $invitation->{files} ); + $c->show_in_list( $invitation->{show_in_list} ); + $c->deleted( $invitation->{deleted} ); + + $c->record(1) unless $c->record; + } + + return $c; +} + +1; diff --git a/lib/Lufi/DB/Invitation/Mysql.pm b/lib/Lufi/DB/Invitation/Mysql.pm new file mode 100644 index 0000000..e265d2e --- /dev/null +++ b/lib/Lufi/DB/Invitation/Mysql.pm @@ -0,0 +1,13 @@ +# vim:set sw=4 ts=4 sts=4 ft=perl expandtab: +package Lufi::DB::Invitation::Mysql; +use Mojo::Base 'Lufi::DB::Invitation'; + +sub new { + my $c = shift; + + $c = $c->SUPER::new(@_); + + return $c; +} + +1; diff --git a/lib/Lufi/DB/Invitation/Pg.pm b/lib/Lufi/DB/Invitation/Pg.pm new file mode 100644 index 0000000..d41ce77 --- /dev/null +++ b/lib/Lufi/DB/Invitation/Pg.pm @@ -0,0 +1,13 @@ +# vim:set sw=4 ts=4 sts=4 ft=perl expandtab: +package Lufi::DB::Invitation::Pg; +use Mojo::Base 'Lufi::DB::Invitation'; + +sub new { + my $c = shift; + + $c = $c->SUPER::new(@_); + + return $c; +} + +1; diff --git a/lib/Lufi/DB/Invitation/SQLite.pm b/lib/Lufi/DB/Invitation/SQLite.pm new file mode 100644 index 0000000..e406363 --- /dev/null +++ b/lib/Lufi/DB/Invitation/SQLite.pm @@ -0,0 +1,14 @@ +# vim:set sw=4 ts=4 sts=4 ft=perl expandtab: +package Lufi::DB::Invitation::SQLite; +use Mojo::Base 'Lufi::DB::Invitation'; + +sub new { + my $c = shift; + + $c = $c->SUPER::new(@_); + $c = $c->_slurp if defined $c->record; + + return $c; +} + +1;