1. Toby Inkster
  2. p5-rdf-crypt

Source

p5-rdf-crypt / lib / RDF / Crypt / Role / DoesEncrypt.pm

package RDF::Crypt::Role::DoesEncrypt;

use 5.010;
use Any::Moose 'Role';

use Crypt::OpenSSL::Bignum qw[];
use Crypt::OpenSSL::RSA qw[];
use File::Slurp qw[slurp];
use Mail::Message qw[];
use Mail::Transport::Send qw[];
use Mail::Transport::Sendmail qw[];
use Mail::Transport::SMTP qw[];
use RDF::TrineX::Functions -shortcuts;

use namespace::clean;

BEGIN {
	$RDF::Crypt::Role::DoesEncrypt::AUTHORITY = 'cpan:TOBYINK';
	$RDF::Crypt::Role::DoesEncrypt::VERSION   = '0.002';
}

requires 'encrypt_text';

sub encrypt_model
{
	my ($self, $model, %opts) = @_;
	$model = rdf_parse(
		$model,
		%opts,
	);
	$self->encrypt_text(
		rdf_string($model),
	);
}

sub send_model_by_email
{
	my ($self, $model, $mailopts, $rdfopts) = @_;
	
	confess("This object was not constructed from a WebID")
		unless $self->webid && $self->webid_model;

	my $transport;
	$transport = Mail::Transport::SMTP->new(%{$mailopts->{smtp}})
		if $mailopts->{smtp};
	$transport = Mail::Transport::Sendmail->new(%{$mailopts->{sendmail}})
		if $mailopts->{sendmail};
	$transport ||= Mail::Transport::Send->new;
	
	confess("No method for sending mail.")
		unless defined $transport;

	my @results = 
		map  { substr($_, 7) }
		grep { /^mailto:.+\@.+$/i }
		map  { $_->{mbox}->value }
		RDF::Query
			-> new(sprintf 'SELECT ?mbox { <%s> foaf:mbox ?mbox } ORDER BY ASC(?mbox)', $self->webid)
			-> execute($self->webid_model)
			-> get_all;
	
	confess("No valid e-mail address found for WebID <@{[ $self->webid ]}>")
		unless @results;
	
	my $crypto = $self->encrypt_model($model, %{ $rdfopts || +{} });
	my $default_from =
		   $RDF::Crypt::SENDER
		|| $ENV{EMAIL_ADDRESS}
		|| ((getlogin||getpwuid($<)||"anonymous").'@'.Sys::Hostname::hostname);

	my %headers = %{ $mailopts->{headers} || +{} };

	my $msg = Mail::Message->build(
		To            => $results[0],
		From          => ($mailopts->{from} || $default_from),
		Subject       => ($mailopts->{subject} || 'Encrypted data'),
		'X-Mailer'    => sprintf('%s/%s', __PACKAGE__, __PACKAGE__->VERSION),
		attach        => Mail::Message::Body::Lines->new(
			data          => ["This data has been encrypted for:\n", $self->webid."\n"],
			mime_type     => 'text/plain',
			disposition   => 'inline',
		),
		attach        => Mail::Message::Body::Lines->new(
			data          => ["$crypto\n"],
			mime_type     => 'application/prs.rdf-xml-crypt;version=0',
			disposition   => 'attachment; filename="'.($mailopts->{filename}||'data.rdf-crypt').'"',
		),
		%headers
	);
	
	return unless $msg->send($transport);
	return $msg->messageId;
}

1;