CDS
view release on metacpan or search on metacpan
sub verifyRemoval {
my $o = shift;
my $actorHash = shift; die 'wrong type '.ref($actorHash).' for $actorHash' if defined $actorHash && ref $actorHash ne 'CDS::Hash';
my $accountHash = shift; die 'wrong type '.ref($accountHash).' for $accountHash' if defined $accountHash && ref $accountHash ne 'CDS::Hash';
my $boxLabel = shift;
my $hash = shift; die 'wrong type '.ref($hash).' for $hash' if defined $hash && ref $hash ne 'CDS::Hash';
return if ! $actorHash;
return 1 if $accountHash->equals($actorHash);
# Get the envelope
my ($bytes, $error) = $o->{store}->get($hash);
return if defined $error;
return 1 if ! defined $bytes;
my $record = CDS::Record->fromObject(CDS::Object->fromBytes($bytes)) // return;
# Allow anyone listed under "updated by"
my $actorHashBytes24 = substr($actorHash->bytes, 0, 24);
for my $child ($record->child('updated by')->children) {
my $hashBytes24 = $child->bytes;
next if length $hashBytes24 != 24;
return 1 if $hashBytes24 eq $actorHashBytes24;
}
return;
}
# A Condensation store accessed through HTTP or HTTPS.
package CDS::HTTPStore;
use parent -norequire, 'CDS::Store';
sub forUrl {
my $class = shift;
my $url = shift;
$url =~ /^(http|https):\/\// || return;
return $class->new($url);
}
sub new {
my $class = shift;
my $url = shift;
return bless {url => $url};
}
sub id {
my $o = shift;
$o->{url} }
sub get {
my $o = shift;
my $hash = shift; die 'wrong type '.ref($hash).' for $hash' if defined $hash && ref $hash ne 'CDS::Hash';
my $keyPair = shift; die 'wrong type '.ref($keyPair).' for $keyPair' if defined $keyPair && ref $keyPair ne 'CDS::KeyPair';
my $response = $o->request('GET', $o->{url}.'/objects/'.$hash->hex, HTTP::Headers->new);
return if $response->code == 404;
return undef, 'get ==> HTTP '.$response->status_line if ! $response->is_success;
return CDS::Object->fromBytes($response->decoded_content(charset => 'none'));
}
sub put {
my $o = shift;
my $hash = shift; die 'wrong type '.ref($hash).' for $hash' if defined $hash && ref $hash ne 'CDS::Hash';
my $object = shift; die 'wrong type '.ref($object).' for $object' if defined $object && ref $object ne 'CDS::Object';
my $keyPair = shift; die 'wrong type '.ref($keyPair).' for $keyPair' if defined $keyPair && ref $keyPair ne 'CDS::KeyPair';
my $headers = HTTP::Headers->new;
$headers->header('Content-Type' => 'application/condensation-object');
my $response = $o->request('PUT', $o->{url}.'/objects/'.$hash->hex, $headers, $keyPair, $object->bytes, 1);
return if $response->is_success;
return 'put ==> HTTP '.$response->status_line;
}
sub book {
my $o = shift;
my $hash = shift; die 'wrong type '.ref($hash).' for $hash' if defined $hash && ref $hash ne 'CDS::Hash';
my $keyPair = shift; die 'wrong type '.ref($keyPair).' for $keyPair' if defined $keyPair && ref $keyPair ne 'CDS::KeyPair';
my $response = $o->request('POST', $o->{url}.'/objects/'.$hash->hex, HTTP::Headers->new, $keyPair, undef, 1);
return if $response->code == 404;
return 1 if $response->is_success;
return undef, 'book ==> HTTP '.$response->status_line;
}
sub list {
my $o = shift;
my $accountHash = shift; die 'wrong type '.ref($accountHash).' for $accountHash' if defined $accountHash && ref $accountHash ne 'CDS::Hash';
my $boxLabel = shift;
my $timeout = shift;
my $keyPair = shift; die 'wrong type '.ref($keyPair).' for $keyPair' if defined $keyPair && ref $keyPair ne 'CDS::KeyPair';
my $boxUrl = $o->{url}.'/accounts/'.$accountHash->hex.'/'.$boxLabel;
my $headers = HTTP::Headers->new;
$headers->header('Condensation-Watch' => $timeout.' ms') if $timeout > 0;
my $needsSignature = $boxLabel ne 'public';
my $response = $o->request('GET', $boxUrl, $headers, $keyPair, undef, $needsSignature);
return undef, 'list ==> HTTP '.$response->status_line if ! $response->is_success;
my $bytes = $response->decoded_content(charset => 'none');
if (length($bytes) % 32 != 0) {
print STDERR 'old procotol', "\n";
my $hashes = [];
for my $line (split /\n/, $bytes) {
push @$hashes, CDS::Hash->fromHex($line) // next;
}
return $hashes;
}
my $countHashes = int(length($bytes) / 32);
return [map { CDS::Hash->fromBytes(substr($bytes, $_ * 32, 32)) } 0 .. $countHashes - 1];
}
sub add {
my $o = shift;
my $accountHash = shift; die 'wrong type '.ref($accountHash).' for $accountHash' if defined $accountHash && ref $accountHash ne 'CDS::Hash';
my $boxLabel = shift;
my $hash = shift; die 'wrong type '.ref($hash).' for $hash' if defined $hash && ref $hash ne 'CDS::Hash';
my $keyPair = shift; die 'wrong type '.ref($keyPair).' for $keyPair' if defined $keyPair && ref $keyPair ne 'CDS::KeyPair';
my $headers = HTTP::Headers->new;
my $needsSignature = $boxLabel ne 'messages';
my $response = $o->request('PUT', $o->{url}.'/accounts/'.$accountHash->hex.'/'.$boxLabel.'/'.$hash->hex, $headers, $keyPair, undef, $needsSignature);
return if $response->is_success;
return 'add ==> HTTP '.$response->status_line;
}
sub remove {
my $o = shift;
my $accountHash = shift; die 'wrong type '.ref($accountHash).' for $accountHash' if defined $accountHash && ref $accountHash ne 'CDS::Hash';
my $boxLabel = shift;
my $hash = shift; die 'wrong type '.ref($hash).' for $hash' if defined $hash && ref $hash ne 'CDS::Hash';
my $keyPair = shift; die 'wrong type '.ref($keyPair).' for $keyPair' if defined $keyPair && ref $keyPair ne 'CDS::KeyPair';
my $headers = HTTP::Headers->new;
my $response = $o->request('DELETE', $o->{url}.'/accounts/'.$accountHash->hex.'/'.$boxLabel.'/'.$hash->hex, $headers, $keyPair, undef, 1);
return if $response->is_success;
return 'remove ==> HTTP '.$response->status_line;
}
sub modify {
my $o = shift;
my $modifications = shift;
my $keyPair = shift; die 'wrong type '.ref($keyPair).' for $keyPair' if defined $keyPair && ref $keyPair ne 'CDS::KeyPair';
my $bytes = $modifications->toRecord->toObject->bytes;
my $needsSignature = $modifications->needsSignature($keyPair);
my $headers = HTTP::Headers->new;
$headers->header('Content-Type' => 'application/condensation-modifications');
my $response = $o->request('POST', $o->{url}.'/accounts', $headers, $keyPair, $bytes, $needsSignature, 1);
return if $response->is_success;
return 'modify ==> HTTP '.$response->status_line;
}
# Executes a HTTP request.
sub request {
my $class = shift;
my $method = shift;
my $url = shift;
( run in 1.655 second using v1.01-cache-2.11-cpan-2398b32b56e )