class Blobs::ApiClient
Attributes
current_user[RW]
token[RW]
Public Instance Methods
add_dir(base_path, rm = false, persist_locally = false)
click to toggle source
# File lib/blobs.rb, line 188 def add_dir(base_path, rm = false, persist_locally = false) raise 'No base path given!' unless base_path blob_ids = [] Dir["#{base_path}/**/*.*"].each do |file| key = file.split('/')[0...-1].join('/') log("Adding file: #{file}") log("Key: #{key}") unless file.include?('.blob') if (blob_id = add_file(file, key, persist_locally)) blob_ids << blob_id File.delete(file) if rm end end end blob_ids end
add_file(file_path, key = 'default', persist_locally = false)
click to toggle source
# File lib/blobs.rb, line 157 def add_file(file_path, key = 'default', persist_locally = false) raise 'No file path given!' unless file_path raise "File doesn't exist!" unless File.file?(file_path) file_json = file_to_json(file_path) resp = create(file_json, key, true) if persist_locally if resp['id'] File.open("#{file_path.gsub(file_json[:file_name], resp['id'])}.blob", 'wb') do |f| f.write(Base64.encode64(file_json.to_json)) f.close end else raise "No blob id for file: #{file_json[:file_name]}" end end resp ? resp['id'] : nil end
all(key = nil)
click to toggle source
# File lib/blobs.rb, line 53 def all(key = nil) raise 'No access token!' unless self.token url = "#{base_url}/blobs" url += "?key=#{CGI::escape(sha256(key))}" if key response = HTTParty.get(url, { headers: headers }) log "Blobs: #{response.parsed_response.inspect}" response.parsed_response.map do |blob| { id: blob['id'], created_at: blob['createdAt'], json: (blob['json'] ? (JSON.parse(decrypt(blob['json'])) rescue nil) : nil), key: blob['key'], file: blob['file'] ? blob['file'] : false } end end
base_url()
click to toggle source
# File lib/blobs.rb, line 18 def base_url ENV['BLOB_STORE_API_BASE_URL'] end
create(json, key = 'default', is_file = false)
click to toggle source
# File lib/blobs.rb, line 78 def create(json, key = 'default', is_file = false) raise 'No access token!' unless self.token raise "No json hash!" unless json raise "No key!" unless key response = HTTParty.post("#{base_url}/blobs", { body: { json: encrypt(json.to_json), key: sha256(key), isFile: is_file }, headers: headers } ) log "Blob created: #{response.parsed_response.inspect}" response.parsed_response end
create_user(email, password)
click to toggle source
# File lib/blobs.rb, line 44 def create_user(email, password) raise "You need to set the master key to create users!" unless master_token user = { email: email, password: password } response = HTTParty.post("#{base_url}/users", body: user, headers: { 'Authorization': "Bearer #{master_token}" }) log "#{response.parsed_response.inspect}" response.parsed_response end
destroy(blob_id)
click to toggle source
# File lib/blobs.rb, line 102 def destroy(blob_id) raise 'No access token!' unless self.token raise "No blob id!" unless blob_id response = HTTParty.delete("#{base_url}/blobs/#{blob_id}", { headers: headers }) log "Blob destroyed: #{response.parsed_response.inspect}" response.parsed_response end
export_key_file(key_file = "
click to toggle source
# File lib/blobs.rb, line 114 def export_key_file(key_file = "#{ENV['HOME']}/.blobs.key.enc") export_file = "#{ENV['HOME']}/blobs.key-#{Time.now.to_i}" decrypt_file(key_file, export_file) export_file end
export_key_file_qrcode(key_file = "
click to toggle source
# File lib/blobs.rb, line 120 def export_key_file_qrcode(key_file = "#{ENV['HOME']}/.blobs.key.enc") encryption_key unless @encryption_key and @iv key_file_json_str = Base64.encode64({ key: @encryption_key, iv: @iv }.to_json) qrcode = RQRCode::QRCode.new(key_file_json_str) png = qrcode.as_png( resize_gte_to: false, resize_exactly_to: false, fill: 'white', color: 'black', size: 240, border_modules: 4, module_px_size: 6, file: nil # path to write ) qrcode_file_path = "#{ENV['HOME']}/blobs.key-#{SecureRandom.hex(4)}#{Time.now.to_i}.png" IO.write(qrcode_file_path, png.to_s) qrcode_file_path end
file_from_json(file_json, path = '/tmp', blob_id = nil)
click to toggle source
# File lib/blobs.rb, line 145 def file_from_json(file_json, path = '/tmp', blob_id = nil) if file_json and file_json['file'] and file_json['file_name'] decoded_string = Base64.decode64(file_json['file']) blob_file_path = "#{path}/#{blob_id ? "#{blob_id}-" : ''}#{file_json['file_name']}" File.open(blob_file_path, 'wb') do |f| f.write(decoded_string) f.close end blob_file_path end end
file_to_json(file_path)
click to toggle source
# File lib/blobs.rb, line 139 def file_to_json(file_path) encoded_string = Base64.encode64(File.open(file_path, 'rb').read) { file: encoded_string, file_name: file_path.split('/').last, file_size: File.size(file_path) } end
find(blob_id)
click to toggle source
# File lib/blobs.rb, line 70 def find(blob_id) raise 'No access token!' unless self.token raise "No blob id!" unless blob_id response = HTTParty.get("#{base_url}/blobs/#{blob_id}", { headers: headers }) log "Blob: #{response.parsed_response.inspect}" response.parsed_response ? JSON.parse(decrypt(response.parsed_response['json'])) : nil end
get_dir(base_path)
click to toggle source
# File lib/blobs.rb, line 205 def get_dir(base_path) raise 'No base path given!' unless base_path files = [] if (blobs = all(base_path)) blobs.each do |blob| if blob[:file] and blob[:json] blob_json = blob[:json] log("Decrypting #{blob_json['file_name']} to #{base_path}...") files << blob_json['file_name'] file_from_json(blob_json, base_path) end end end files end
get_file(blob_id, path = '/tmp')
click to toggle source
# File lib/blobs.rb, line 181 def get_file(blob_id, path = '/tmp') if (blob = find(blob_id)) return file_from_json(blob, path, blob_id) if blob['file'] and blob['file_name'] end nil end
log(msg)
click to toggle source
# File lib/blobs.rb, line 26 def log(msg) puts msg if DEBUG end
login(email, password)
click to toggle source
# File lib/blobs.rb, line 30 def login(email, password) auth = { username: email, password: password } response = HTTParty.post("#{base_url}/auth", basic_auth: auth) if response.code == 201 and response.parsed_response log "#{response.parsed_response.inspect}" self.current_user = response.parsed_response['user'] self.token = response.parsed_response['token'] encryption_key return self.token end nil end
master_token()
click to toggle source
# File lib/blobs.rb, line 22 def master_token ENV['MASTER_KEY'] end
restore_local_dir(base_path, rm = false)
click to toggle source
# File lib/blobs.rb, line 221 def restore_local_dir(base_path, rm = false) files = [] Dir["#{base_path}/**/*.*"].each do |file| if file.include?('.blob') decoded_string = Base64.decode64(File.open(file, 'rb').read) file_json = JSON.parse(decoded_string) dir = file.split('/')[0...-1].join('/') file_from_json(file_json, dir) files << "#{dir}/#{file_json['file_name']}" File.delete(file) if rm end end files end
update(blob_id, json, key = 'default')
click to toggle source
# File lib/blobs.rb, line 92 def update(blob_id, json, key = 'default') raise 'No access token!' unless self.token raise "No blob id!" unless json raise "No json hash!" unless json response = HTTParty.put("#{base_url}/blobs/#{blob_id}", { body: { json: encrypt(json.to_json), key: sha256(key) }, headers: headers }) log "Blob update: #{response.parsed_response.inspect}" response.parsed_response end
update_file(blob_id, file_path, key = 'default')
click to toggle source
# File lib/blobs.rb, line 175 def update_file(blob_id, file_path, key = 'default') raise 'No file path given!' unless file_path raise "File doesn't exist!" unless File.file?(file_path) update(blob_id, file_to_json(file_path), key) end
user_token()
click to toggle source
# File lib/blobs.rb, line 110 def user_token Base64.decode64(self.current_user['userToken']) end
Private Instance Methods
decrypt(enc_str)
click to toggle source
# File lib/blobs.rb, line 255 def decrypt(enc_str) decipher = OpenSSL::Cipher::AES256.new :CBC decipher.decrypt decipher.key = encryption_key decipher.iv = get_iv decipher.update(Base64.decode64(enc_str).strip) + decipher.final end
decrypt_file(file_path, dec_file_path)
click to toggle source
# File lib/blobs.rb, line 321 def decrypt_file(file_path, dec_file_path) raise 'No user token!' unless self.user_token cipher = OpenSSL::Cipher::AES256.new :CBC cipher.decrypt cipher.key = self.user_token buf = "" File.open(dec_file_path, 'wb') do |outf| File.open(file_path, 'rb') do |inf| while inf.read(4096, buf) outf << cipher.update(buf) end outf << cipher.final end end true end
encrypt(str)
click to toggle source
# File lib/blobs.rb, line 247 def encrypt(str) cipher = OpenSSL::Cipher::AES256.new :CBC cipher.encrypt cipher.key = encryption_key cipher.iv = get_iv Base64.encode64(cipher.update(str) + cipher.final).strip end
encrypt_file(file_path, enc_file_path)
click to toggle source
# File lib/blobs.rb, line 302 def encrypt_file(file_path, enc_file_path) raise 'No user token!' unless self.user_token cipher = OpenSSL::Cipher::AES256.new :CBC cipher.encrypt cipher.key = self.user_token buf = "" File.open(enc_file_path, 'wb') do |outf| File.open(file_path, 'rb') do |inf| while inf.read(4096, buf) outf << cipher.update(buf) end outf << cipher.final end end true end
encryption_key()
click to toggle source
# File lib/blobs.rb, line 263 def encryption_key return @encryption_key if @encryption_key key_file = "#{ENV['HOME']}/.blobs.key.enc" decrypted_key_file = "#{key_file.gsub('.enc', '')}-#{SecureRandom.hex(4)}#{Time.now.to_i}" if File.file?(key_file) if decrypt_file(key_file, decrypted_key_file) key_file_contents = File.read(decrypted_key_file) key_file_yml = YAML.load(Base64.strict_decode64(key_file_contents)) if key_file_yml[:key] and key_file_yml[:iv] @iv = key_file_yml[:iv] @encryption_key = key_file_yml[:key] File.delete(decrypted_key_file) return @encryption_key else raise "Key file is corrupt!" end else raise "Key file couldn't be decrypted!" end else cipher = OpenSSL::Cipher::AES256.new :CBC @encryption_key = Digest::SHA256.hexdigest(cipher.random_key)[0..31] @iv = Digest::SHA256.hexdigest(cipher.random_iv)[0..15] key_file_yml = { key: @encryption_key, iv: @iv } File.open(decrypted_key_file, 'wb') do |f| enc = Base64.strict_encode64(key_file_yml.to_yaml) f.write(enc) f.close end File.delete(decrypted_key_file) if encrypt_file(decrypted_key_file, key_file) end @encryption_key end
get_iv()
click to toggle source
# File lib/blobs.rb, line 298 def get_iv @iv end
headers(additional_headers = {})
click to toggle source
# File lib/blobs.rb, line 237 def headers(additional_headers = {}) additional_headers.merge({ 'Authorization': "Bearer #{self.token}" }) end
sha256(str)
click to toggle source
# File lib/blobs.rb, line 243 def sha256(str) Base64.encode64(Digest::SHA256.digest(str)).strip end