Adding verification email.

This commit is contained in:
sergiotarxz 2022-04-24 03:01:21 +02:00
parent f2cf883f34
commit deeb0da8cd
18 changed files with 353 additions and 54 deletions

View File

@ -24,6 +24,7 @@ my $build = Module::Build->new(
'Email::Valid' => 0, 'Email::Valid' => 0,
'Crypt::Bcrypt' => 0, 'Crypt::Bcrypt' => 0,
'Email::Sender' => 0, 'Email::Sender' => 0,
'HTML::Entities' => 0,
}, },
install_path => { install_path => {
'templates' => "$HOME/.local/share/peace/template", 'templates' => "$HOME/.local/share/peace/template",

View File

@ -7,6 +7,7 @@ use warnings;
use Test::Most tests => 2; use Test::Most tests => 2;
use Crypt::URandom q/urandom/;
use DateTime; use DateTime;
use Peace; use Peace;
@ -32,6 +33,7 @@ use Peace::DAO::Developer;
verified => 0, verified => 0,
secret_bcrypt => $secret_bcrypt secret_bcrypt => $secret_bcrypt
); );
$developer->email($developer->email =~ s/\@/unpack('H*', urandom(100)).'@'/er);
my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh ); my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh );
## WHEN ## WHEN

View File

@ -10,6 +10,7 @@ use Data::Dumper;
use Test::Most tests => 4; use Test::Most tests => 4;
use DateTime; use DateTime;
use Crypt::URandom q/urandom/;
use Peace; use Peace;
use Peace::DB; use Peace::DB;
@ -30,6 +31,7 @@ use Peace::Test::Mock::Model::Application;
my $dbh = Peace::DB->dbh( config => $config ); my $dbh = Peace::DB->dbh( config => $config );
my $developer = Peace::Test::Mock::Model::Developer->new; my $developer = Peace::Test::Mock::Model::Developer->new;
$developer->email($developer->email =~ s/\@/unpack('H*', urandom(100)).'@'/er);
my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh ); my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh );
$developer_dao->create( developer => $developer ); $developer_dao->create( developer => $developer );
@ -60,6 +62,7 @@ use Peace::Test::Mock::Model::Application;
my $secret_bcrypt = 'hola'; my $secret_bcrypt = 'hola';
my $developer = Peace::Test::Mock::Model::Developer->new; my $developer = Peace::Test::Mock::Model::Developer->new;
$developer->email($developer->email =~ s/\@/unpack('H*', urandom(100)).'@'/er);
my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh ); my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh );
$developer_dao->create( developer => $developer ); $developer_dao->create( developer => $developer );

View File

@ -10,6 +10,7 @@ use Data::Dumper;
use Test::Most tests => 2; use Test::Most tests => 2;
use DateTime; use DateTime;
use Crypt::URandom q/urandom/;
use Peace; use Peace;
use Peace::DB; use Peace::DB;
@ -32,6 +33,7 @@ use Peace::Test::Mock::Model::Release;
my $dbh = Peace::DB->dbh( config => $config ); my $dbh = Peace::DB->dbh( config => $config );
my $developer = Peace::Test::Mock::Model::Developer->new; my $developer = Peace::Test::Mock::Model::Developer->new;
$developer->email($developer->email =~ s/\@/unpack('H*', urandom(100)).'@'/er);
my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh ); my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh );
$developer_dao->create( developer => $developer ); $developer_dao->create( developer => $developer );

View File

@ -8,6 +8,7 @@ use warnings;
use Test::Most tests => 2; use Test::Most tests => 2;
use DateTime; use DateTime;
use Crypt::URandom q/urandom/;
use Peace; use Peace;
use Peace::DB; use Peace::DB;
@ -31,6 +32,8 @@ use Peace::Test::Mock::Model::Build;
my $release_dao = Peace::DAO::Release->new( dbh => $dbh ); my $release_dao = Peace::DAO::Release->new( dbh => $dbh );
my $application_dao = Peace::DAO::Application->new( dbh => $dbh ); my $application_dao = Peace::DAO::Application->new( dbh => $dbh );
my $build_dao = Peace::DAO::Build->new( dbh => $dbh ); my $build_dao = Peace::DAO::Build->new( dbh => $dbh );
my $developer = $build->release->application->developer;
$developer->email($developer->email =~ s/\@/unpack('H*', urandom(100)).'@'/er);
$developer_dao->create( $developer_dao->create(
developer => $build->release->application->developer ); developer => $build->release->application->developer );
$build->release->application->app_id( $build->release->application->app_id(

View File

@ -8,6 +8,9 @@
<li> <li>
<a href="lib/Peace.pm.html">Peace</a> <a href="lib/Peace.pm.html">Peace</a>
</li> </li>
<li>
<a href="lib/Peace/Controller/Application.pm.html">Peace::Controller::Application</a>
</li>
<li> <li>
<a href="lib/Peace/Controller/Developer.pm.html">Peace::Controller::Developer</a> <a href="lib/Peace/Controller/Developer.pm.html">Peace::Controller::Developer</a>
</li> </li>
@ -32,6 +35,9 @@
<li> <li>
<a href="lib/Peace/DB.pm.html">Peace::DB</a> <a href="lib/Peace/DB.pm.html">Peace::DB</a>
</li> </li>
<li>
<a href="lib/Peace/Email.pm.html">Peace::Email</a>
</li>
<li> <li>
<a href="lib/Peace/Model/Application.pm.html">Peace::Model::Application</a> <a href="lib/Peace/Model/Application.pm.html">Peace::Model::Application</a>
</li> </li>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Peace::Controller::Application - Application&#39;s http endpoint.</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<link href="mailto:Alpine@build-edge-aarch64.nonet" rev="made" />
</head>
<body>
<ul id="index">
<li><a href="#NAME">NAME</a></li>
<li><a href="#SYNOPSIS">SYNOPSIS</a></li>
<li><a href="#DESCRIPTION">DESCRIPTION</a></li>
<li><a href="#METHODS">METHODS</a>
<ul>
<li><a href="#developer_application_post">developer_application_post</a></li>
</ul>
</li>
<li><a href="#SEE-ALSO">SEE ALSO</a></li>
</ul>
<h1 id="NAME">NAME</h1>
<p>Peace::Controller::Application - Application&#39;s http endpoint.</p>
<h1 id="SYNOPSIS">SYNOPSIS</h1>
<pre><code># This object is used by mojolicious.</code></pre>
<h1 id="DESCRIPTION">DESCRIPTION</h1>
<p>Peace::Controller::Application allows to interact using a json http api with the <a href="../Model/Application.pm.html">Peace::Model::Application</a> objects in Peace.</p>
<h1 id="METHODS">METHODS</h1>
<p>Peace::Controller::Developer implements the following methods:</p>
<h2 id="developer_application_post">developer_application_post</h2>
<pre><code># To be used by mojolicious.</code></pre>
<p>Creates a application in db with the data given by the user.</p>
<h1 id="SEE-ALSO">SEE ALSO</h1>
<p><a href="../Model/Application.pm.html">Peace::Model::Application</a>, <a href="../DAO/Application.pm.html">Peace::DAO::Application</a></p>
</body>
</html>

View File

@ -24,6 +24,7 @@
<ul> <ul>
<li><a href="#create">create</a></li> <li><a href="#create">create</a></li>
<li><a href="#recover_by_uuid">recover_by_uuid</a></li> <li><a href="#recover_by_uuid">recover_by_uuid</a></li>
<li><a href="#recover_by_identifier">recover_by_identifier</a></li>
</ul> </ul>
</li> </li>
<li><a href="#SEE-ALSO">SEE ALSO</a></li> <li><a href="#SEE-ALSO">SEE ALSO</a></li>
@ -73,6 +74,12 @@ my $developer = $developer_dao-&gt;recover_by_uuid( uuid =&gt; $uuid );</code></
<p>Recovers the <a href="../Model/Developer.pm.html">Peace::Model::Developer</a> associated from an uuid from database.</p> <p>Recovers the <a href="../Model/Developer.pm.html">Peace::Model::Developer</a> associated from an uuid from database.</p>
<h2 id="recover_by_identifier">recover_by_identifier</h2>
<pre><code>my $developer = $developer_dao-&gt;recover_by_identifier( identifier =&gt; $identifier );</code></pre>
<p>Recovers the <a href="../Model/Developer.pm.html">Peace::Model::Developer</a> associated from an identifier from database.</p>
<h1 id="SEE-ALSO">SEE ALSO</h1> <h1 id="SEE-ALSO">SEE ALSO</h1>
<p><a href="../DB.pm.html">Peace::DB</a>, <a href="../Model/Developer.pm.html">Peace::Model::Developer</a></p> <p><a href="../DB.pm.html">Peace::DB</a>, <a href="../Model/Developer.pm.html">Peace::Model::Developer</a></p>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Peace::Email - The mail sender module for Peace.</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<link href="mailto:Alpine@build-edge-aarch64.nonet" rev="made" />
</head>
<body>
<ul id="index">
<li><a href="#NAME">NAME</a></li>
<li><a href="#SYNOPSIS">SYNOPSIS</a></li>
<li><a href="#DESCRIPTION">DESCRIPTION</a></li>
<li><a href="#INSTANCE-METHODS">INSTANCE METHODS</a>
<ul>
<li><a href="#new">new</a></li>
</ul>
</li>
<li><a href="#METHODS">METHODS</a>
<ul>
<li><a href="#sendmail">sendmail</a></li>
</ul>
</li>
<li><a href="#SEE-ALSO">SEE ALSO</a></li>
</ul>
<h1 id="NAME">NAME</h1>
<p>Peace::Email - The mail sender module for Peace.</p>
<h1 id="SYNOPSIS">SYNOPSIS</h1>
<pre><code>my $mailer = Peace::Email-&gt;new;
$mailer-&gt;sendmail(
to =&gt; &#39;larry@perl,org&#39;,
text =&gt; &#39;hola&#39;,
html =&gt; &#39;&lt;b&gt;hola&lt;/b&gt;&#39;,
subject =&gt; &#39;Patch&#39;,
);</code></pre>
<h1 id="DESCRIPTION">DESCRIPTION</h1>
<p>Peace::Email reads the Peace config to determine the credentials to send mail and does an abstraction around those.</p>
<h1 id="INSTANCE-METHODS">INSTANCE METHODS</h1>
<p>Peace::Email implements the following instance methods:</p>
<h2 id="new">new</h2>
<pre><code>my $mailer = Peace::Email-&gt;new;</code></pre>
<p>Instances a new mailer.</p>
<h1 id="METHODS">METHODS</h1>
<p>Peace::Email implements the following methods:</p>
<h2 id="sendmail">sendmail</h2>
<pre><code>$mailer-&gt;sendmail(
to =&gt; &#39;larry@perl,org&#39;,
text =&gt; &#39;hola&#39;,
html =&gt; &#39;&lt;b&gt;hola&lt;/b&gt;&#39;,
subject =&gt; &#39;Patch&#39;,
);</code></pre>
<p>Sends a mail to the given mail address.</p>
<h1 id="SEE-ALSO">SEE ALSO</h1>
<p><a href="../Peace.pm.html">Peace</a></p>
</body>
</html>

View File

@ -22,6 +22,7 @@
</li> </li>
<li><a href="#METHODS">METHODS</a> <li><a href="#METHODS">METHODS</a>
<ul> <ul>
<li><a href="#to_json">to_json</a></li>
<li><a href="#uuid">uuid</a></li> <li><a href="#uuid">uuid</a></li>
<li><a href="#date_creation">date_creation</a></li> <li><a href="#date_creation">date_creation</a></li>
<li><a href="#name">name</a></li> <li><a href="#name">name</a></li>
@ -85,6 +86,12 @@
<p>Peace::Model::Application implements the following methods:</p> <p>Peace::Model::Application implements the following methods:</p>
<h2 id="to_json">to_json</h2>
<pre><code>my $json = $application-&gt;to_json;</code></pre>
<p>Retrieves the json representation of the application.</p>
<h2 id="uuid">uuid</h2> <h2 id="uuid">uuid</h2>
<pre><code>my $uuid = $application-&gt;uuid; <pre><code>my $uuid = $application-&gt;uuid;

View File

@ -23,6 +23,7 @@
<li><a href="#METHODS">METHODS</a> <li><a href="#METHODS">METHODS</a>
<ul> <ul>
<li><a href="#to_json">to_json</a></li> <li><a href="#to_json">to_json</a></li>
<li><a href="#login">login</a></li>
<li><a href="#applications">applications</a></li> <li><a href="#applications">applications</a></li>
<li><a href="#uuid">uuid</a></li> <li><a href="#uuid">uuid</a></li>
<li><a href="#date_creation">date_creation</a></li> <li><a href="#date_creation">date_creation</a></li>
@ -33,6 +34,7 @@
<li><a href="#stripe_id">stripe_id</a></li> <li><a href="#stripe_id">stripe_id</a></li>
<li><a href="#country">country</a></li> <li><a href="#country">country</a></li>
<li><a href="#verified">verified</a></li> <li><a href="#verified">verified</a></li>
<li><a href="#verification_secret">verification_secret</a></li>
</ul> </ul>
</li> </li>
<li><a href="#SEE-ALSO">SEE ALSO</a></li> <li><a href="#SEE-ALSO">SEE ALSO</a></li>
@ -86,6 +88,12 @@
<p>Renders the developer in a json like structure.</p> <p>Renders the developer in a json like structure.</p>
<h2 id="login">login</h2>
<pre><code>my $logged = $developer-&gt;login( secret =&gt; $secret );</code></pre>
<p>Returns true if the login is successful, false otherwise.</p>
<h2 id="applications">applications</h2> <h2 id="applications">applications</h2>
<pre><code>my $applications = $developer-&gt;applications;</code></pre> <pre><code>my $applications = $developer-&gt;applications;</code></pre>
@ -156,12 +164,20 @@ $developer-&gt;country($country);</code></pre>
<h2 id="verified">verified</h2> <h2 id="verified">verified</h2>
<pre><code>my $verified = $developer-&gt;verified <pre><code>my $verified = $developer-&gt;verified;
$developer-&gt;verified($verified);</code></pre> $developer-&gt;verified($verified);</code></pre>
<p>Allows to retrieve and set the developer verified.</p> <p>Allows to retrieve and set the developer verified.</p>
<h2 id="verification_secret">verification_secret</h2>
<pre><code>my $verification_secret = $developer-&gt;verification_secret;
$developer-&gt;verification_secret($verification_secret);</code></pre>
<p>Allows to retrieve and set the developer verification_secret.</p>
<h1 id="SEE-ALSO">SEE ALSO</h1> <h1 id="SEE-ALSO">SEE ALSO</h1>
<p><a href="../DAO/Developer.pm.html">Peace::DAO::Developer</a>, <a href="Application.pm.html">Peace::Model::Application</a></p> <p><a href="../DAO/Developer.pm.html">Peace::DAO::Developer</a>, <a href="Application.pm.html">Peace::Model::Application</a></p>

View File

@ -26,6 +26,7 @@
<li><a href="#validate_request">validate_request</a></li> <li><a href="#validate_request">validate_request</a></li>
<li><a href="#developer">developer</a></li> <li><a href="#developer">developer</a></li>
<li><a href="#developer_post">developer_post</a></li> <li><a href="#developer_post">developer_post</a></li>
<li><a href="#developer_application_post">developer_application_post</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -78,10 +79,16 @@
<h2 id="developer_post">developer_post</h2> <h2 id="developer_post">developer_post</h2>
<pre><code>my $developer_post = $swagger-&gt;developer_post</code></pre> <pre><code>my $developer_post = $swagger-&gt;developer_post;</code></pre>
<p>Returns the schema of the post request to the /developer enpoint.</p> <p>Returns the schema of the post request to the /developer enpoint.</p>
<h2 id="developer_application_post">developer_application_post</h2>
<pre><code>my $developer_application_post = $swagger-&gt;developer_application_post;</code></pre>
<p>Returns the schema of the post request to the /developer/:identifier/application endpoint.</p>
</body> </body>

View File

@ -11,12 +11,14 @@ use Data::Dumper;
use Const::Fast; use Const::Fast;
use Peace::Swagger;
use Crypt::Bcrypt qw/bcrypt/; use Crypt::Bcrypt qw/bcrypt/;
use Crypt::URandom qw/urandom/; use Crypt::URandom qw/urandom/;
use HTML::Entities;
use Peace; use Peace;
use Peace::DB; use Peace::DB;
use Peace::Email;
use Peace::Swagger;
use Peace::Model::Developer; use Peace::Model::Developer;
use Peace::DAO::Developer; use Peace::DAO::Developer;
@ -28,6 +30,8 @@ sub post {
my $json = $self->req->json; my $json = $self->req->json;
my $peace = Peace->new; my $peace = Peace->new;
my $config = $peace->peace_config; my $config = $peace->peace_config;
my $mailer = Peace::Email->new;
my $url = $config->{url};
my $dbh = Peace::DB->dbh( config => $config ); my $dbh = Peace::DB->dbh( config => $config );
my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh ); my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh );
@ -53,6 +57,13 @@ sub post {
$self->render( status => 400, text => $@ ); $self->render( status => 400, text => $@ );
return; return;
} }
my $verification_url = "$url/web/account-verification/@{[$developer->verification_secret]}";
my $verification_url_html = HTML::Entities::encode_entities($verification_url);
$mailer->sendmail( to => $developer->email,
text => "Verify your account at $verification_url",
html => "Verify your account at <a href=\"$verification_url_html\">$verification_url_html</a>.",
subject => 'Verify your Peace account.',
);
$self->render( json => $developer->to_json() ); $self->render( json => $developer->to_json() );
} }
1; 1;

View File

@ -47,13 +47,14 @@ EOF
my $result; my $result;
eval { eval {
$result = $dbh->selectrow_hashref( $result = $dbh->selectrow_hashref(
$insert, undef, $developer->secret_bcrypt, $insert, undef,
$developer->name, $developer->surname, $developer->email, $developer->secret_bcrypt, $developer->name,
$developer->country, $developer->verified $developer->surname, $developer->email,
$developer->country, $developer->verified
); );
}; };
if ($@) { if ($@) {
if ($@ =~ /duplicate key value/) { if ( $@ =~ /duplicate key value/ ) {
die "Email already registered."; die "Email already registered.";
} }
die $@; die $@;
@ -63,6 +64,7 @@ EOF
my $new_developer = $self->recover_by_uuid( uuid => $uuid ); my $new_developer = $self->recover_by_uuid( uuid => $uuid );
$developer->date_creation( $new_developer->date_creation ) $developer->date_creation( $new_developer->date_creation )
if defined $new_developer->date_creation; if defined $new_developer->date_creation;
$developer->verification_secret( $new_developer->verification_secret );
return $developer; return $developer;
} }
} }
@ -78,16 +80,16 @@ EOF
my $self = shift; my $self = shift;
my %params = $validator->(@_); my %params = $validator->(@_);
my $uuid = $params{uuid}; my $uuid = $params{uuid};
my $dbh = $self->_dbh; my $dbh = $self->_dbh;
my $result = $dbh->selectrow_hashref( <<'EOF', undef, $uuid ); my $result = $dbh->selectrow_hashref( <<'EOF', undef, $uuid );
SELECT uuid, date_creation, secret_bcrypt, name, surname, email, stripe_id, country, verified SELECT uuid, date_creation, secret_bcrypt, name, surname, email, stripe_id, country, verified, verification_secret
FROM developers FROM developers
WHERE uuid = ?; WHERE uuid = ?;
EOF EOF
if (!defined $result) { if ( !defined $result ) {
die "No such developer $uuid."; die "No such developer $uuid.";
} }
for my $key (keys %$result) { for my $key ( keys %$result ) {
delete $result->{$key} unless defined $result->{$key}; delete $result->{$key} unless defined $result->{$key};
} }
@ -110,19 +112,19 @@ EOF
); );
sub recover_by_identifier { sub recover_by_identifier {
my $self = shift; my $self = shift;
my %params = $validator->(@_); my %params = $validator->(@_);
my $identifier =$params{identifier}; my $identifier = $params{identifier};
my $dbh = $self->_dbh; my $dbh = $self->_dbh;
my $result = $dbh->selectrow_hashref( <<'EOF', undef, $identifier ); my $result = $dbh->selectrow_hashref( <<'EOF', undef, $identifier );
SELECT uuid, date_creation, secret_bcrypt, name, surname, email, stripe_id, country, verified SELECT uuid, date_creation, secret_bcrypt, name, surname, email, stripe_id, country, verified, verification_secret
FROM developers FROM developers
WHERE email = $1 or uuid::text = $1; WHERE email = $1 or uuid::text = $1;
EOF EOF
if (!defined $result) { if ( !defined $result ) {
die "No such developer $identifier."; die "No such developer $identifier.";
} }
for my $key (keys %$result) { for my $key ( keys %$result ) {
delete $result->{$key} unless defined $result->{$key}; delete $result->{$key} unless defined $result->{$key};
} }
@ -136,11 +138,13 @@ EOF
return $developer; return $developer;
} }
} }
sub _dbh { sub _dbh {
my $self = shift; my $self = shift;
return $self->{dbh}; return $self->{dbh};
} }
1; 1;
=encoding utf8 =encoding utf8
=head1 NAME =head1 NAME

View File

@ -34,6 +34,12 @@ my @migrations = (
stripe_id TEXT, stripe_id TEXT,
country TEXT NOT NULL, country TEXT NOT NULL,
verified BOOL DEFAULT false, verified BOOL DEFAULT false,
verification_secret TEXT NOT NULL
DEFAULT encode(
sha512(
gen_random_uuid()::text::bytea
)::bytea, \'hex\'
) UNIQUE,
PRIMARY KEY (uuid) PRIMARY KEY (uuid)
);', );',
'CREATE TABLE applications ( 'CREATE TABLE applications (

View File

@ -5,6 +5,8 @@ use v5.30.0;
use strict; use strict;
use warnings; use warnings;
use Encode qw/decode/;
use Peace; use Peace;
use Params::ValidationCompiler qw/validation_for/; use Params::ValidationCompiler qw/validation_for/;
@ -22,60 +24,63 @@ sub new {
{ {
my $validator = validation_for( my $validator = validation_for(
params => { params => {
text => { type => Str }, text => { type => Str },
html => { type => Str }, html => { type => Str },
to => { type => Str }, to => { type => Str },
subject => { type => Str },
} }
); );
sub sendmail { sub sendmail {
my $self = shift; my $self = shift;
my %params = $validator->(@_); my %params = $validator->(@_);
my ( $text, $html, $to ) = @params{qw/text html to/}; my ( $text, $html, $to, $subject ) = @params{qw/text html to subject/};
my @parts = ( my @parts = (
Email::MIME->create( Email::MIME->create(
attributes => { attributes => {
content_type => 'multipart/alternative', content_type => 'multipart/alternative',
encoding => 'base64',
}, },
parts => [ parts => [
Email::MIME->create( Email::MIME->create(
attributes => { attributes => {
charset => 'UTF-8', charset => 'UTF-8',
content_type => 'text/plain', content_type => 'text/plain',
encoding => "quoted-printable", encoding => 'base64',
disposition => 'inline', disposition => 'inline',
}, },
body_str => $text, body_str => decode('utf-8', $text),
), ),
Email::MIME->create( Email::MIME->create(
attributes => { attributes => {
charset => 'UTF-8', charset => 'UTF-8',
content_type => 'text/html', content_type => 'text/html',
encoding => "quoted-printable", encoding => 'base64',
disposition => 'inline', disposition => 'inline',
}, },
body_str => $html, body_str => decode('utf-8', $html),
) )
] ]
) )
); );
my $email = Email::MIME->create( my $email = Email::MIME->create(
header_str => [ header_str => [
From => Peace->new->peace_config->{smtp}{sasl_username}, From => Peace->new->peace_config->{smtp}{sasl_username},
To => $to, To => $to,
Subject => $subject,
], ],
attributes => { attributes => {
encoding => 'base64', encoding => 'base64',
content_type => 'multipart/mixed' content_type => 'multipart/mixed'
}, },
parts => [@parts], parts => [@parts],
); );
Email::Sender::Simple::send( 'Email::Sender::Simple', $email, Email::Sender::Simple::send( 'Email::Sender::Simple', $email,
{ transport => $self->generate_transport } ); { transport => $self->_generate_transport } );
} }
} }
sub generate_transport { sub _generate_transport {
my $peace_config = Peace->new->peace_config; my $peace_config = Peace->new->peace_config;
my $transport = Email::Sender::Transport::SMTP->new( my $transport = Email::Sender::Transport::SMTP->new(
hosts => [ $peace_config->{smtp}{smtp_host} ], hosts => [ $peace_config->{smtp}{smtp_host} ],
@ -87,3 +92,55 @@ sub generate_transport {
return $transport; return $transport;
} }
1; 1;
=encoding utf8
=head1 NAME
Peace::Email - The mail sender module for Peace.
=head1 SYNOPSIS
my $mailer = Peace::Email->new;
$mailer->sendmail(
to => 'larry@perl,org',
text => 'hola',
html => '<b>hola</b>',
subject => 'Patch',
);
=head1 DESCRIPTION
Peace::Email reads the Peace config to determine the credentials
to send mail and does an abstraction around those.
=head1 INSTANCE METHODS
Peace::Email implements the following instance methods:
=head2 new
my $mailer = Peace::Email->new;
Instances a new mailer.
=head1 METHODS
Peace::Email implements the following methods:
=head2 sendmail
$mailer->sendmail(
to => 'larry@perl,org',
text => 'hola',
html => '<b>hola</b>',
subject => 'Patch',
);
Sends a mail to the given mail address.
=head1 SEE ALSO
L<Peace>
=cut

View File

@ -17,13 +17,14 @@ use Peace::DAO::Application;
params => { params => {
uuid => { type => Str, optional => 1 }, uuid => { type => Str, optional => 1 },
date_creation => { type => InstanceOf ['DateTime'], optional => 1 }, date_creation => { type => InstanceOf ['DateTime'], optional => 1 },
secret_bcrypt => { type => Str }, secret_bcrypt => { type => Str },
name => { type => Str }, name => { type => Str },
surname => { type => Str }, surname => { type => Str },
email => { type => Str }, email => { type => Str },
stripe_id => { type => Str, optional => 1 }, stripe_id => { type => Str, optional => 1 },
country => { type => Str }, country => { type => Str },
verified => { type => Bool }, verified => { type => Bool },
verification_secret => { type => Str, optional => 1 },
dbh => { type => HasMethods ['selectall_arrayref'], optional => 1 }, dbh => { type => HasMethods ['selectall_arrayref'], optional => 1 },
} }
); );
@ -55,12 +56,13 @@ sub to_json {
secret => { type => Str }, secret => { type => Str },
} }
); );
sub login { sub login {
my $self = shift; my $self = shift;
my %params = $validator->(@_); my %params = $validator->(@_);
my $secret = $params{secret}; my $secret = $params{secret};
my $secret_bcrypt = $self->secret_bcrypt; my $secret_bcrypt = $self->secret_bcrypt;
return bcrypt_check($secret, $secret_bcrypt); return bcrypt_check( $secret, $secret_bcrypt );
} }
} }
@ -207,6 +209,20 @@ sub applications {
} }
} }
{
my $validator =
validation_for( params => [ { type => Str, optional => 1 } ] );
sub verification_secret {
my $self = shift;
if (@_) {
my ($new_verification_secret) = $validator->(@_);
$self->{verification_secret} = $new_verification_secret;
}
return $self->{verification_secret};
}
}
sub _dbh { sub _dbh {
my $self = shift; my $self = shift;
return $self->{dbh}; return $self->{dbh};
@ -342,12 +358,20 @@ Allows to retrieve and set the developer country.
=head2 verified =head2 verified
my $verified = $developer->verified my $verified = $developer->verified;
$developer->verified($verified); $developer->verified($verified);
Allows to retrieve and set the developer verified. Allows to retrieve and set the developer verified.
=head2 verification_secret
my $verification_secret = $developer->verification_secret;
$developer->verification_secret($verification_secret);
Allows to retrieve and set the developer verification_secret.
=head1 SEE ALSO =head1 SEE ALSO
L<Peace::DAO::Developer>, L<Peace::Model::Application> L<Peace::DAO::Developer>, L<Peace::Model::Application>

View File

@ -46,7 +46,7 @@ EOF
results => [ ['uuid'], [$uuid], ] results => [ ['uuid'], [$uuid], ]
}; };
$sql = <<'EOF'; $sql = <<'EOF';
SELECT uuid, date_creation, secret_bcrypt, name, surname, email, stripe_id, country, verified SELECT uuid, date_creation, secret_bcrypt, name, surname, email, stripe_id, country, verified, verification_secret
FROM developers FROM developers
WHERE uuid = ?; WHERE uuid = ?;
EOF EOF
@ -60,11 +60,12 @@ EOF
'surname', 'email', 'surname', 'email',
'country', 'verified', 'country', 'verified',
'secret_bcrypt', 'date_creation', 'secret_bcrypt', 'date_creation',
'stripe_id' 'stripe_id', 'verification_secret'
], ],
[ [
$uuid, $name, $surname, $email, $country, $verified, $uuid, $name, $surname, $email, $country, $verified,
$secret_bcrypt, $formatter->format_datetime($datetime), undef $secret_bcrypt, $formatter->format_datetime($datetime),
undef, 'aaa'
] ]
], ],
}; };
@ -81,7 +82,7 @@ EOF
my $dbh = DBI->connect( 'DBI:Mock:', '', '' ); my $dbh = DBI->connect( 'DBI:Mock:', '', '' );
my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh ); my $developer_dao = Peace::DAO::Developer->new( dbh => $dbh );
my $sql = <<'EOF'; my $sql = <<'EOF';
SELECT uuid, date_creation, secret_bcrypt, name, surname, email, stripe_id, country, verified SELECT uuid, date_creation, secret_bcrypt, name, surname, email, stripe_id, country, verified, verification_secret
FROM developers FROM developers
WHERE uuid = ?; WHERE uuid = ?;
EOF EOF
@ -105,11 +106,12 @@ EOF
'surname', 'email', 'surname', 'email',
'country', 'verified', 'country', 'verified',
'secret_bcrypt', 'date_creation', 'secret_bcrypt', 'date_creation',
'stripe_id' 'stripe_id', 'verification_secret'
], ],
[ [
$uuid, $name, $surname, $email, $country, $verified, $uuid, $name, $surname, $email, $country, $verified,
$secret_bcrypt, $formatter->format_datetime($datetime), undef $secret_bcrypt, $formatter->format_datetime($datetime),
undef, 'aaa'
] ]
], ],
}; };