Class: Fling::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/fling/config.rb

Overview

Configuration for the local Tahoe cluster

Constant Summary collapse

BEGIN_MARKER =
"-----BEGIN ENCRYPTED FLING CONFIGURATION-----\n"
END_MARKER =
"------END ENCRYPTED FLING CONFIGURATION------"
CONFIG_KEYS =
%w(introducer convergence salt dropcap)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Config

Returns a new instance of Config.



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/fling/config.rb', line 48

def initialize(options = {})
  CONFIG_KEYS.each do |key|
    fail ArgumentError, "missing key: #{key}" unless options[key]
    instance_variable_set("@#{key}", options[key])
  end

  fail ConfigError, "bad introducer: #{@introducer}" if URI(@introducer).scheme != "pb"
  fail ConfigError, "bad dropcap: #{@dropcap}" unless @dropcap.start_with?("URI:DIR2:")

  %w(convergence salt).each do |key|
    b32_value = options[key]

    begin
      value = Encoding.decode(b32_value)
    rescue
      raise ConfigError, "bad #{key} (base32 error): #{b32_value}"
    end

    fail ConfigError, "bad #{key} (wrong size): #{b32_value}" if value.size != 32
  end
end

Class Method Details

.decrypt(password, ciphertext) ⇒ Object

Decrypt an encrypted configuration



34
35
36
37
38
39
40
41
# File 'lib/fling/config.rb', line 34

def self.decrypt(password, ciphertext)
  matches = ciphertext.match(/#{BEGIN_MARKER}(.*)#{END_MARKER}/m)
  fail ConfigError, "couldn't find fling configuration (corrupted file?)" unless matches

  new(Box.decrypt(password, Base64.decode64(matches[1])))
rescue RbNaCl::CryptoError # bad password
  raise ConfigError, "couldn't decrypt configuration (corrupted file or bad password?)"
end

.encrypt(password, config) ⇒ Object

Generate an encrypted configuration



28
29
30
31
# File 'lib/fling/config.rb', line 28

def self.encrypt(password, config)
  ciphertext = Box.encrypt(password, generate_json(config))
  BEGIN_MARKER + Base64.encode64(ciphertext) + END_MARKER
end

.from_json(json) ⇒ Object

Parse configuration from JSON



23
24
25
# File 'lib/fling/config.rb', line 23

def self.from_json(json)
  new(JSON.parse(json))
end

.generate_json(config) ⇒ Object

Generate a JSON configuration



44
45
46
# File 'lib/fling/config.rb', line 44

def self.generate_json(config)
  new(config).as_json
end

.load_json(file) ⇒ Object

Load configuration from a JSON file



18
19
20
# File 'lib/fling/config.rb', line 18

def self.load_json(file)
  from_json File.read(file)
end

Instance Method Details

#as_jsonObject



88
89
90
91
92
93
94
95
# File 'lib/fling/config.rb', line 88

def as_json
  {
    introducer:  introducer,
    convergence: convergence,
    salt:        salt,
    dropcap:     dropcap
  }
end

#render(path) ⇒ Object

Render the configuration to the given path



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/fling/config.rb', line 71

def render(path)
  tahoe_bin = File.expand_path("~/#{Fling::Install::TAHOE_DIR}/bin/tahoe")
  system "#{tahoe_bin} create-node > /dev/null"

  @nickname = `whoami`
  @introducer_furl = introducer

  config_template = File.expand_path("../../../templates/tahoe.cfg.erb", __FILE__)
  tahoe_config = ERB.new(File.read(config_template)).result(binding)

  File.open(File.join(path, "tahoe.cfg"), "w", 0600) { |file| file << tahoe_config }

  secrets = File.join(path, "private")
  File.open(File.join(secrets, "convergence"), "w", 0600) { |file| file << convergence }
  File.open(File.join(secrets, "aliases"), "w", 0600) { |file| file << "dropcap: #{dropcap}" }
end