App-Phoebe

 view release on metacpan or  search on metacpan

lib/App/Phoebe/Capsules.pm  view on Meta::CPAN

    my $backup_file = $backup_dir . "/" . encode_utf8($id);
    mkdir($backup_dir) unless -d $backup_dir;
    rename $file, $backup_file if -f $file;
    result($stream, "30", to_url($stream, $host, $capsule_space, $capsule));
  } else {
    $log->info("Delete for $capsule");
    success($stream);
    $stream->write("# Delete a file in " . ucfirst($capsule) . "\n");
    $stream->write("Deleting a file moves it to the backup.\n");
    my @files;
    @files = grep { $_ ne "backup" } read_dir($dir) if -d $dir;
    if (not @files) {
      $stream->write("There are no files to delete.\n") unless @files;
    } else {
      $stream->write("Files:\n");
      for my $file (sort @files) {
	print_link($stream, $host, $capsule_space, $file, "$capsule/delete/$file");
      };
    }
  }
  return 1;
}

sub serve_capsule_access {
  my ($stream, $host, $capsule, $token) = @_;
  my $fingerprint = $stream->handle->get_fingerprint();
  my $target = first { $_->[1] eq $token } @capsule_tokens;
  if (not $fingerprint) {
    $log->info("Attempt to access a capsule without client certificate");
    result($stream, "60", "You need a client certificate to access this capsule");
  } elsif ($target) {
    if ($fingerprint ne $target->[2]) {
      $log->info("Access to capsule granted");
      # if the user is testing it, then the two fingerprints are the same and no
      # equivalency needs to be saved
      $capsule_equivalent{$fingerprint} = $target->[2];
      my $dir = $server->{wiki_dir};
      write_binary("$dir/fingerprint_equivalents",
		   join("\n", map { $_ . " " . $capsule_equivalent{$_} }
			keys %capsule_equivalent));
    } else {
      $log->info("Access to capsule unnecessary for the owner");
    }
    result($stream, "30", to_url($stream, $host, $capsule_space, $capsule));
  } else {
    $log->info("Access to capsule denied");
    success($stream);
    $stream->write("This password is invalid\n");
  }
  return 1;
}

sub serve_capsule_sharing {
  my ($stream, $host, $capsule) = @_;
  my $name = capsule_name($stream);
  return 1 unless is_my_capsule($stream, $name, $capsule, 'share');
  $log->info("Share capsule");
  my $token = capsule_name(sprintf "-------%04X%04X%04X", rand(0xffff), rand(0xffff), rand(0xffff));
  push(@capsule_tokens, [time, $token, $stream->handle->get_fingerprint()]);
  # forget old access tokens in ten minutes
  Mojo::IOLoop->timer(601 => \&capsule_token_cleanup);
  success($stream);
  $stream->write("# Share access to " . ucfirst($capsule) . "\n");
  $stream->write("This password is valid for ten minutes: $token\n");
  return 1;
}

sub is_my_capsule {
  my ($stream, $name, $capsule, $verb) = @_;
  if (not $name) {
    $log->info("Attempt to $verb a capsule without client certificate");
    result($stream, "60", "You need a client certificate to $verb this capsule");
    return 0;
  } elsif ($capsule and $name ne $capsule) {
    $log->info("Attempt to $verb the wrong capsule");
    result($stream, "60", "You need a different client certificate to $verb this capsule");
    return 0;
  }
  return 1;
}

sub serve_capsule_page {
  my ($stream, $host, $capsule, $id) = @_;
  my $dir = capsule_dir($host, $capsule);
  my $file = $dir . "/" . encode_utf8($id);
  if (-f $file) {
    $log->info("Serving $file");
    # this works for text files, too!
    success($stream, mime_type($id));
    $stream->write(read_binary($file));
  } else {
    $log->info("Serving invitation to upload $file");
    success($stream);
    $stream->write("This file does not exist. Upload it using Titan!\n");
    $stream->write("=> gemini://transjovian.org/titan What is Titan?\n");
  }
  return 1;
}

sub serve_capsule_menu {
  my ($stream, $host, $capsule) = @_;
  my $name = capsule_name($stream);
  my $dir = capsule_dir($host, $capsule);
  my @files;
  @files = read_dir($dir) if -d $dir;
  my $has_backup = first { $_ eq "backup" } @files;
  @files = grep { $_ ne "backup" } @files if $has_backup;
  success($stream);
  $log->info("Serving $capsule");
  $stream->write("# " . ucfirst($capsule) . "\n");
  if ($name) {
    if ($name eq $capsule) {
      print_link($stream, $host, $capsule_space, "Specify file for upload", "$capsule/upload");
      print_link($stream, $host, $capsule_space, "Delete file", "$capsule/delete") if @files;
      print_link($stream, $host, $capsule_space, "Share access with other people or other devices", "$capsule/share");
      print_link($stream, $host, $capsule_space, "Access backup", "$capsule/backup") if $has_backup;
      print_link($stream, $host, $capsule_space, "Download archive", "$capsule/archive") if @files;
    } elsif (@capsule_tokens) {
      print_link($stream, $host, $capsule_space, "Access this capsule", "$capsule/access");
    }
  }



( run in 0.808 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )