require 'clamp' require 'siren' module Siren module CLI class SongfileCommand < Clamp::Command subcommand %w(c conv convert), "Convert songfile to resources" do parameter "SONGFILE", "the Songfile" def execute song = Siren::Song.load(songfile) puts song.to_stack.to_yaml end end end class CryptoCommand < Clamp::Command subcommand %w(g gen genkeys), "Generate encryption keys" do option %w(-f --force), :flag, "overwrite keys if they already exist" option %w(-k --privkey), "FILE", "private key file", default: "private.jwk" option %w(-p --pubkey), "FILE", "public key file", default: "public.jwk" def execute if File.exists?(privkey) && !force? STDERR.puts "Won't overwrite #{privkey}. Delete it first if you want to generate a new key." exit 1 end private, public = Siren::Crypto.genkeys public.to_file(privkey) private.to_file(pubkey) puts "Keys generated. Keep #{privkey} secret. Give #{pubkey} to whoever needs it." puts "Thumbprint: #{JOSE::JWK.thumbprint(private)}" end end subcommand %w(e enc encrypt), "Encrypt data using public key" do option %w(-k --pubkey), "FILE", "public key file", default: "public.jwk" parameter "WORDS ...", "the data to encrypt", attribute_name: :words def execute require "jose" key = JOSE::JWK.from_file(pubkey) STDERR.puts "multiple arguments will be joined with single spaces" if words.length > 1 plain = words.join(" ") cyphertext = key.box_encrypt(plain)[0].compact puts cyphertext end end subcommand %w(d dec decrypt), "Decrypt data using private key" do option %w(-k --privkey), "FILE", "private key file", default: "private.jwk" parameter "CYPHERTEXT", "the data to decrypt", attribute_name: :cyphertext def execute require "jose" key = JOSE::JWK.from_file(privkey) puts key.block_decrypt(cyphertext)[0] end end end class SirenCommand < Clamp::Command subcommand %w(ver version), "Show version" do def execute puts "siren #{Siren::VERSION}" exit(0) end end subcommand %w(c crypto cryptography), "Cryptography (JOSE) commands", CryptoCommand subcommand %w(s song songs songfile), "Songfile commands", SongfileCommand end def self.start SirenCommand.run end end end