summaryrefslogtreecommitdiffstats
path: root/app/controllers/api
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2020-06-02 19:24:53 +0200
committerGitHub <noreply@github.com>2020-06-02 19:24:53 +0200
commit5d8398c8b8b51ee7363e7d45acc560f489783e34 (patch)
tree1e0b663049feafdc003ad3c01b25bf5d5d793402 /app/controllers/api
parent9b7e3b4774d47c184aa759364d41f40e0cdfa210 (diff)
Add E2EE API (#13820)
Diffstat (limited to 'app/controllers/api')
-rw-r--r--app/controllers/api/v1/crypto/deliveries_controller.rb30
-rw-r--r--app/controllers/api/v1/crypto/encrypted_messages_controller.rb59
-rw-r--r--app/controllers/api/v1/crypto/keys/claims_controller.rb25
-rw-r--r--app/controllers/api/v1/crypto/keys/counts_controller.rb17
-rw-r--r--app/controllers/api/v1/crypto/keys/queries_controller.rb26
-rw-r--r--app/controllers/api/v1/crypto/keys/uploads_controller.rb29
6 files changed, 186 insertions, 0 deletions
diff --git a/app/controllers/api/v1/crypto/deliveries_controller.rb b/app/controllers/api/v1/crypto/deliveries_controller.rb
new file mode 100644
index 00000000000..aa9df6e03b2
--- /dev/null
+++ b/app/controllers/api/v1/crypto/deliveries_controller.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class Api::V1::Crypto::DeliveriesController < Api::BaseController
+ before_action -> { doorkeeper_authorize! :crypto }
+ before_action :require_user!
+ before_action :set_current_device
+
+ def create
+ devices.each do |device_params|
+ DeliverToDeviceService.new.call(current_account, @current_device, device_params)
+ end
+
+ render_empty
+ end
+
+ private
+
+ def set_current_device
+ @current_device = Device.find_by!(access_token: doorkeeper_token)
+ end
+
+ def resource_params
+ params.require(:device)
+ params.permit(device: [:account_id, :device_id, :type, :body, :hmac])
+ end
+
+ def devices
+ Array(resource_params[:device])
+ end
+end
diff --git a/app/controllers/api/v1/crypto/encrypted_messages_controller.rb b/app/controllers/api/v1/crypto/encrypted_messages_controller.rb
new file mode 100644
index 00000000000..a67b03eb4f2
--- /dev/null
+++ b/app/controllers/api/v1/crypto/encrypted_messages_controller.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+class Api::V1::Crypto::EncryptedMessagesController < Api::BaseController
+ LIMIT = 80
+
+ before_action -> { doorkeeper_authorize! :crypto }
+ before_action :require_user!
+ before_action :set_current_device
+
+ before_action :set_encrypted_messages, only: :index
+ after_action :insert_pagination_headers, only: :index
+
+ def index
+ render json: @encrypted_messages, each_serializer: REST::EncryptedMessageSerializer
+ end
+
+ def clear
+ @current_device.encrypted_messages.up_to(params[:up_to_id]).delete_all
+ render_empty
+ end
+
+ private
+
+ def set_current_device
+ @current_device = Device.find_by!(access_token: doorkeeper_token)
+ end
+
+ def set_encrypted_messages
+ @encrypted_messages = @current_device.encrypted_messages.paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
+ end
+
+ def insert_pagination_headers
+ set_pagination_headers(next_path, prev_path)
+ end
+
+ def next_path
+ api_v1_encrypted_messages_url pagination_params(max_id: pagination_max_id) if records_continue?
+ end
+
+ def prev_path
+ api_v1_encrypted_messages_url pagination_params(min_id: pagination_since_id) unless @encrypted_messages.empty?
+ end
+
+ def pagination_max_id
+ @encrypted_messages.last.id
+ end
+
+ def pagination_since_id
+ @encrypted_messages.first.id
+ end
+
+ def records_continue?
+ @encrypted_messages.size == limit_param(LIMIT)
+ end
+
+ def pagination_params(core_params)
+ params.slice(:limit).permit(:limit).merge(core_params)
+ end
+end
diff --git a/app/controllers/api/v1/crypto/keys/claims_controller.rb b/app/controllers/api/v1/crypto/keys/claims_controller.rb
new file mode 100644
index 00000000000..34b21a38096
--- /dev/null
+++ b/app/controllers/api/v1/crypto/keys/claims_controller.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class Api::V1::Crypto::Keys::ClaimsController < Api::BaseController
+ before_action -> { doorkeeper_authorize! :crypto }
+ before_action :require_user!
+ before_action :set_claim_results
+
+ def create
+ render json: @claim_results, each_serializer: REST::Keys::ClaimResultSerializer
+ end
+
+ private
+
+ def set_claim_results
+ @claim_results = devices.map { |device_params| ::Keys::ClaimService.new.call(current_account, device_params[:account_id], device_params[:device_id]) }.compact
+ end
+
+ def resource_params
+ params.permit(device: [:account_id, :device_id])
+ end
+
+ def devices
+ Array(resource_params[:device])
+ end
+end
diff --git a/app/controllers/api/v1/crypto/keys/counts_controller.rb b/app/controllers/api/v1/crypto/keys/counts_controller.rb
new file mode 100644
index 00000000000..ffd7151b782
--- /dev/null
+++ b/app/controllers/api/v1/crypto/keys/counts_controller.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class Api::V1::Crypto::Keys::CountsController < Api::BaseController
+ before_action -> { doorkeeper_authorize! :crypto }
+ before_action :require_user!
+ before_action :set_current_device
+
+ def show
+ render json: { one_time_keys: @current_device.one_time_keys.count }
+ end
+
+ private
+
+ def set_current_device
+ @current_device = Device.find_by!(access_token: doorkeeper_token)
+ end
+end
diff --git a/app/controllers/api/v1/crypto/keys/queries_controller.rb b/app/controllers/api/v1/crypto/keys/queries_controller.rb
new file mode 100644
index 00000000000..0851d797d33
--- /dev/null
+++ b/app/controllers/api/v1/crypto/keys/queries_controller.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class Api::V1::Crypto::Keys::QueriesController < Api::BaseController
+ before_action -> { doorkeeper_authorize! :crypto }
+ before_action :require_user!
+ before_action :set_accounts
+ before_action :set_query_results
+
+ def create
+ render json: @query_results, each_serializer: REST::Keys::QueryResultSerializer
+ end
+
+ private
+
+ def set_accounts
+ @accounts = Account.where(id: account_ids).includes(:devices)
+ end
+
+ def set_query_results
+ @query_results = @accounts.map { |account| ::Keys::QueryService.new.call(account) }.compact
+ end
+
+ def account_ids
+ Array(params[:id]).map(&:to_i)
+ end
+end
diff --git a/app/controllers/api/v1/crypto/keys/uploads_controller.rb b/app/controllers/api/v1/crypto/keys/uploads_controller.rb
new file mode 100644
index 00000000000..fc4abf63b3a
--- /dev/null
+++ b/app/controllers/api/v1/crypto/keys/uploads_controller.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class Api::V1::Crypto::Keys::UploadsController < Api::BaseController
+ before_action -> { doorkeeper_authorize! :crypto }
+ before_action :require_user!
+
+ def create
+ device = Device.find_or_initialize_by(access_token: doorkeeper_token)
+
+ device.transaction do
+ device.account = current_account
+ device.update!(resource_params[:device])
+
+ if resource_params[:one_time_keys].present? && resource_params[:one_time_keys].is_a?(Enumerable)
+ resource_params[:one_time_keys].each do |one_time_key_params|
+ device.one_time_keys.create!(one_time_key_params)
+ end
+ end
+ end
+
+ render json: device, serializer: REST::Keys::DeviceSerializer
+ end
+
+ private
+
+ def resource_params
+ params.permit(device: [:device_id, :name, :fingerprint_key, :identity_key], one_time_keys: [:key_id, :key, :signature])
+ end
+end