From f880ea46cee9f2e1138535a52e9316c4a927b38c Mon Sep 17 00:00:00 2001 From: Martin Artnik Date: Mon, 13 Feb 2023 11:32:18 +0100 Subject: [PATCH] Add connected device logging [SCI-7632] --- app/models/connected_device.rb | 37 +++++++++++++++++++ config/application.rb | 13 +++++++ ...20230207140811_create_connected_devices.rb | 15 ++++++++ 3 files changed, 65 insertions(+) create mode 100644 app/models/connected_device.rb create mode 100644 db/migrate/20230207140811_create_connected_devices.rb diff --git a/app/models/connected_device.rb b/app/models/connected_device.rb new file mode 100644 index 000000000..2557682c6 --- /dev/null +++ b/app/models/connected_device.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class ConnectedDevice < ApplicationRecord + belongs_to :oauth_access_token, class_name: 'Doorkeeper::AccessToken' + + after_destroy :revoke_token + + def self.for_user(user) + where(oauth_access_token_id: Doorkeeper::AccessToken.select(:id).where(resource_owner_id: user.id)) + end + + def self.from_request_headers(headers, token = nil) + current_token = Doorkeeper::AccessToken.find_by( + token: headers['Authorization'].gsub(/Bearer\s/, '') + ) + + return unless token || current_token + + connected_device = ConnectedDevice.find_or_initialize_by(uid: headers['Device-Id']) + connected_device.update!( + name: headers['Device-Name'], + metadata: { + os: headers['Device-Os'], + app_version: headers['Device-App-Version'] + }.compact, + last_seen_at: Time.current, + oauth_access_token_id: token&.id || current_token&.id + ) + connected_device + end + + private + + def revoke_token + oauth_access_token.revoke + end +end diff --git a/config/application.rb b/config/application.rb index bf486722c..e8513830d 100644 --- a/config/application.rb +++ b/config/application.rb @@ -69,6 +69,19 @@ module Scinote config.to_prepare do # Only Authorization endpoint Doorkeeper::AuthorizationsController.layout 'sign_in_halt' + + # Add Connected Device logging + Doorkeeper::TokensController.class_eval do + after_action :log_connected_device, only: :create + + private + + def log_connected_device + return if @authorize_response.is_a?(Doorkeeper::OAuth::ErrorResponse) + + ConnectedDevice.from_request_headers(request.headers, @authorize_response&.token) + end + end end config.action_view.field_error_proc = Proc.new { |html_tag, instance| diff --git a/db/migrate/20230207140811_create_connected_devices.rb b/db/migrate/20230207140811_create_connected_devices.rb new file mode 100644 index 000000000..fea978686 --- /dev/null +++ b/db/migrate/20230207140811_create_connected_devices.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class CreateConnectedDevices < ActiveRecord::Migration[6.1] + def change + create_table :connected_devices do |t| + t.string :uid + t.string :name + t.references :oauth_access_token, null: false, foreign_key: true + t.json :metadata + t.timestamp :last_seen_at + + t.timestamps + end + end +end