# Manages self authentication responses class SelfAuthResponseManagerService STATUS_ERR = 'errored'.freeze STATUS_REJ = 'rejected'.freeze STATUS_OK = 'accepted'.freeze STATUS_COM = 'completed'.freeze STATUS_RECIEVED = 'received'.freeze def initialize(broadcaster) @broadcaster = broadcaster end # Processes a Self authentication response def process_response(self_auth_response) return if self_auth_response.nil? cid = self_auth_response.id.split('_').first.split('::').last channel = "conversation_#{cid}_channel" if self_auth_response.errored? broadcast_status_change channel, STATUS_ERR, message: 'A timeout ocured while waiting for your device response' return end if self_auth_response.rejected? broadcast_status_change channel, STATUS_REJ return end unless admin?(self_auth_response.from) broadcast_status_change channel, STATUS_ERR, message: 'You are forbidden to access this service' return end user = set_user_token(self_auth_response.from, self_auth_response) broadcast_status_change channel, STATUS_COM, token: user[:token] end private # creates or updates a user setting a random token. def set_user_token(selfid, self_auth_response) user = { token: SecureRandom.uuid, selfid: selfid, facts: {} } SelfAuthRails.auth_facts.each do |fact| user[:facts][fact] = self_auth_response.attestation_values_for(fact).first end u = SelfAuthRails.session_class.find_by(selfid: user[:selfid]) u = SelfAuthRails.session_class.new(selfid: user[:selfid]) if u.nil? u.token = user[:token] SelfAuthRails.fact_mapping.each do |fact_name, field| u.send("#{field}=", user[:facts][fact_name.to_sym]) end u.save! user end # broadcasts a status change through websockets to the web client def broadcast_status_change(channel, status, opts = {}) token = opts.fetch(:token, '') message = opts.fetch(:message, '') type = opts.fetch(:type, 'auth') @broadcaster.broadcast channel, { status: status, token: token, message: message, type: type } end # checks if the given id is in the admins list def admin?(id) return true unless ENV.include? 'ADMIN_IDS' ENV['ADMIN_IDS'].split(',').include? id end end