Skip to content

Commit

Permalink
add support for api keys
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Jenkins committed Apr 28, 2015
1 parent b3fe032 commit a298025
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 3 deletions.
23 changes: 22 additions & 1 deletion lib/Email/SendGrid/Transport/REST.pm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ sub new
@_,
}, $class;

if ( defined($self->{username}) && defined($self->{api_key}) )
{
die "Must only specify username/password or api key, not both";
}

if ( !(defined($self->{username}) && defined($self->{password})) && !defined($self->{api_key}) )
{
die "Must speicfy username/password or api key";
}

return $self;
}

Expand Down Expand Up @@ -69,7 +79,10 @@ sub deliver
# Build the query

my $query = 'https://' . $self->{server} . $self->{path} . "?";
$query .= "api_user=" . uri_escape($self->{username}) . "&api_key=" . uri_escape($self->{password});
if ( defined($self->{username}) )
{
$query .= "api_user=" . uri_escape($self->{username}) . "&api_key=" . uri_escape($self->{password});
}

# Add recipients
foreach my $i ( 0..(scalar(@$toAddr)-1) )
Expand Down Expand Up @@ -150,6 +163,10 @@ sub send

my $ua = LWP::UserAgent->new( timeout => $self->{timeout}, agent => 'sendgrid/' . $VERSION . ';perl' );

if ( defined($self->{api_key}) )
{
$ua->default_header('Authorization' => "Bearer $self->{api_key}");
}
my $response = $ua->get($query);

return { errors => [ $response->status_line() ] } if ( !$response->is_success );
Expand Down Expand Up @@ -245,6 +262,10 @@ Your SendGrid username
Your SendGrid password
=item api_key
Your SendGrid API key
=item server
The server to connect to (default is sendgrid.com)
Expand Down
21 changes: 19 additions & 2 deletions lib/Email/SendGrid/Transport/SMTP.pm
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,23 @@ sub new
$self->{domain} = hostname();
}

croak "username must be specified" if ( !defined($self->{username}) );
croak "password must be specified" if ( !defined($self->{password}) );
croak "TLS is required for port 587" if ( !$self->{tls} && $self->{port} == 587 );

if ( defined($self->{username}) && defined($self->{api_key}) )
{
die "Must only specify username/password or api key, not both";
}

if ( !(defined($self->{username}) && defined($self->{password})) && !defined($self->{api_key}) )
{
die "Must speicfy username/password or api key";
}

if ( defined($self->{api_key}) )
{
$self->{username} = "apikey";
$self->{password} = delete $self->{api_key};
}
return $self;
}

Expand Down Expand Up @@ -125,6 +138,10 @@ Your SendGrid username
Your SendGrid password
=item api_key
Your SendGrid API key
=item server
The server to connect to (default is smtp.sendgrid.net)
Expand Down
109 changes: 109 additions & 0 deletions t/lib/Email/SendGrid/Transport/REST/Test.pm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use MIME::Entity;
use Email::SendGrid;
use Email::SendGrid::Transport::REST;
use Test::MockObject::Extends;
use Test::MockModule;
use URI::Escape;
use Encode;
use JSON;
Expand Down Expand Up @@ -68,6 +69,25 @@ sub getSGObject
return $sg;
}

sub create : Test(no_plan)
{
eval {
my $trans = Email::SendGrid::Transport::REST->new( username => 'u' );
};
ok($@ =~ /Must speicfy username\/password or api key at/, "only providing username generated error");

eval {
my $trans = Email::SendGrid::Transport::REST->new( password => 'u' );
};
ok($@ =~ /Must speicfy username\/password or api key at/, "only providing password generated error");

eval {
my $trans = Email::SendGrid::Transport::REST->new( username => 'u', api_key => 'k' );
};
ok($@ =~ /Must only specify username\/password or api key, not both at/, "providing username and api key generated error");

}

sub deliver : Test(no_plan)
{
my $deliv;
Expand Down Expand Up @@ -171,4 +191,93 @@ sub deliveryError : Test
is($res, "errormsg", 'error handling');
}

sub send_up : Test(no_plan)
{
my $deliv = Test::MockObject::Extends->new(Email::SendGrid::Transport::REST->new(username => 'u', password => 'p'));
my $content = { value => 1 };
my $response = HTTP::Response->new('200', "ok", [], to_json($content));
my $mm = Test::MockModule->new('LWP::UserAgent');
my $obj;
$mm->mock('new' => sub {
$obj = Test::MockObject->new();
$obj->set_always('default_header' => 1);
$obj->mock('get' => sub { return $response } );
return $obj;
});

my $query = "query";
my $resp = $deliv->send($query);

cmp_deeply($resp, $content, "sent");
my ($func, $args) = $obj->next_call();
is($func, 'get', "made call to get");
shift(@$args);
cmp_deeply($args, [$query], " with proper args");

($func, $args) = $obj->next_call();
is($func, undef, "all lwp calls accounted for");

$response = HTTP::Response->new('403', 'bad error');
$resp = $deliv->send($query);
cmp_deeply($resp, {errors => ['403 bad error']}, "error returned" );

($func, $args) = $obj->next_call();
is($func, 'get', "made call to get");
shift(@$args);
cmp_deeply($args, [$query], " with proper args");

($func, $args) = $obj->next_call();
is($func, undef, "all lwp calls accounted for");

}

sub send_apikey : Test(no_plan)
{
my $deliv = Test::MockObject::Extends->new(Email::SendGrid::Transport::REST->new(api_key => 'k'));
my $content = { value => 1 };
my $response = HTTP::Response->new('200', "ok", [], to_json($content));
my $mm = Test::MockModule->new('LWP::UserAgent');
my $obj;
$mm->mock('new' => sub {
$obj = Test::MockObject->new();
$obj->set_always('default_header' => 1);
$obj->mock('get' => sub { return $response } );
return $obj;
});

my $query = "query";
my $resp = $deliv->send($query);

cmp_deeply($resp, $content, "sent");
my ($func, $args) = $obj->next_call();
is($func, 'default_header', "made call to set header");
shift(@$args);
cmp_deeply($args,['Authorization','Bearer k'], " with proper api key header");

($func, $args) = $obj->next_call();
is($func, 'get', "made call to get");
shift(@$args);
cmp_deeply($args, [$query], " with proper args");

($func, $args) = $obj->next_call();
is($func, undef, "all lwp calls accounted for");

$response = HTTP::Response->new('403', 'bad error');
$resp = $deliv->send($query);
cmp_deeply($resp, {errors => ['403 bad error']}, "error returned" );

($func, $args) = $obj->next_call();
is($func, 'default_header', "made call to set header");
shift(@$args);
cmp_deeply($args,['Authorization','Bearer k'], " with proper api key header");

($func, $args) = $obj->next_call();
is($func, 'get', "made call to get");
shift(@$args);
cmp_deeply($args, [$query], " with proper args");

($func, $args) = $obj->next_call();
is($func, undef, "all lwp calls accounted for");

}
1;
21 changes: 21 additions & 0 deletions t/lib/Email/SendGrid/Transport/SMTP/Test.pm
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,27 @@ sub delivery : Test()
is($res, undef, 'normal delivery');
}

sub create : Test(no_plan)
{
eval {
my $trans = Email::SendGrid::Transport::SMTP->new( username => 'u' );
};
ok($@ =~ /Must speicfy username\/password or api key at/, "only providing username generated error");

eval {
my $trans = Email::SendGrid::Transport::SMTP->new( password => 'u' );
};
ok($@ =~ /Must speicfy username\/password or api key at/, "only providing password generated error");

eval {
my $trans = Email::SendGrid::Transport::SMTP->new( username => 'u', api_key => 'k' );
};
ok($@ =~ /Must only specify username\/password or api key, not both at/, "providing username and api key generated error");

my $trans = Email::SendGrid::Transport::SMTP->new( api_key => 'k' );
is($trans->{username}, 'apikey', "username set to apikey");
is($trans->{password}, 'k', 'password set to apikey value')
}
###################################################################################################
# Tests for the SMTP transaction
sub connection_refused : Test()
Expand Down

0 comments on commit a298025

Please sign in to comment.