diff options
author | Azul <azul@riseup.net> | 2018-01-15 18:21:44 +0100 |
---|---|---|
committer | Azul <azul@riseup.net> | 2018-01-18 16:43:23 +0100 |
commit | b8ba4f27a82868e0b3338b4af761f7c44226e729 (patch) | |
tree | 45b495e18bab72508342b86cd42ab3d56ed1eacc /app | |
parent | fd2fc85c2daf60605641cc582d75134a10e7b4a4 (diff) |
(WIP) first steps towards implementing keys API
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/api/keys_controller.rb | 63 | ||||
-rw-r--r-- | app/models/keyring.rb | 38 |
2 files changed, 101 insertions, 0 deletions
diff --git a/app/controllers/api/keys_controller.rb b/app/controllers/api/keys_controller.rb new file mode 100644 index 0000000..d4cb759 --- /dev/null +++ b/app/controllers/api/keys_controller.rb @@ -0,0 +1,63 @@ +class Api::KeysController < ApiController + + before_filter :require_login + before_filter :require_enabled + + # get /keys + def index + keys = identity.keys.map do |k,v| + [k, JSON.parse(v)] + end + render json: keys.to_h + end + + def show + render json: JSON.parse(identity.keys[params[:id]]) + end + + def create + keyring.create type, value + head :no_content + rescue Keyring::Error, ActionController::ParameterMissing => e + render status: 422, json: {error: e.message} + end + + def update + keyring.update type, rev: rev, value: value + head :no_content + rescue Keyring::Error, ActionController::ParameterMissing => e + render status: 422, json: {error: e.message} + end + + protected + + def require_enabled + if !current_user.enabled? + access_denied + end + end + + def service_level + current_user.effective_service_level + end + + def type + params.require :type + end + + def value + params.require :value + end + + def rev + params.require :rev + end + + def keyring + @keyring ||= Keyring.new identity + end + + def identity + @identity ||= Identity.for(current_user) + end +end diff --git a/app/models/keyring.rb b/app/models/keyring.rb new file mode 100644 index 0000000..6779d5d --- /dev/null +++ b/app/models/keyring.rb @@ -0,0 +1,38 @@ +# +# Keyring +# +# A collection of cryptographic keys. +# + +class Keyring + class Error < RuntimeError + end + + def initialize(storage) + @storage = storage + end + + def create(type, value) + raise Error, "key already exists" if storage.keys[type].present? + storage.set_key type, {type: type, value: value, rev: new_rev}.to_json + storage.save + end + + def update(type, rev:, value:) + old_rev = key_of_type(type)['rev'] + raise Error, "wrong revision: #{rev}" unless old_rev == rev + storage.set_key type, {type: type, value: value, rev: new_rev}.to_json + storage.save + end + + def key_of_type(type) + JSON.parse(storage.keys[type]) + end + + protected + attr_reader :storage + + def new_rev + SecureRandom.urlsafe_base64(8) + end +end |