Skip to content

Commit

Permalink
Tokens serialization (#1250)
Browse files Browse the repository at this point in the history
  • Loading branch information
dks17 authored and MaicolBen committed Mar 23, 2019
1 parent c34495d commit f929fb4
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 21 deletions.
24 changes: 3 additions & 21 deletions app/models/devise_token_auth/concerns/active_record_support.rb
Original file line number Diff line number Diff line change
@@ -1,34 +1,16 @@
require_relative 'tokens_serialization'

module DeviseTokenAuth::Concerns::ActiveRecordSupport
extend ActiveSupport::Concern

included do
serialize :tokens, JSON unless tokens_has_json_column_type?

# can't set default on text fields in mysql, simulate here instead.
after_save :set_empty_token_hash
after_initialize :set_empty_token_hash
serialize :tokens, DeviseTokenAuth::TokensSerialization
end

class_methods do
# It's abstract replacement .find_by
def dta_find_by(attrs = {})
find_by(attrs)
end

protected

def tokens_has_json_column_type?
database_exists? && table_exists? && columns_hash['tokens'] && columns_hash['tokens'].type.in?([:json, :jsonb])
end

def database_exists?
ActiveRecord::Base.connection_pool.with_connection { |con| con.active? } rescue false
end
end

protected

def set_empty_token_hash
self.tokens ||= {} if has_attribute?(:tokens)
end
end
19 changes: 19 additions & 0 deletions app/models/devise_token_auth/concerns/tokens_serialization.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module DeviseTokenAuth::TokensSerialization
# Serialization hash to json
def self.dump(object)
object.each_value(&:compact!) unless object.nil?
JSON.generate(object)
end

# Deserialization json to hash
def self.load(json)
case json
when String
JSON.parse(json)
when NilClass
{}
else
json
end
end
end
70 changes: 70 additions & 0 deletions test/models/concerns/tokens_serialization_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
require 'test_helper'

if DEVISE_TOKEN_AUTH_ORM == :active_record
describe 'DeviseTokenAuth::TokensSerialization' do
let(:ts) { DeviseTokenAuth::TokensSerialization }
let(:user) { FactoryBot.create(:user) }
let(:tokens) do
# Сreate all possible token's attributes combinations
user.create_token
2.times { user.create_new_auth_token(user.tokens.first[0]) }
user.create_new_auth_token
user.create_token

user.tokens
end
let(:json) { JSON.generate(tokens) }

it 'is defined' do
assert_equal(ts.present?, true)
assert_kind_of(Module, ts)
end

describe '.load(json)' do
let(:default) { {} }

it 'is defined' do
assert_respond_to(ts, :load)
end

it 'handles nil' do
assert_equal(ts.load(nil), default)
end

it 'handles string' do
assert_equal(ts.load(json), JSON.parse(json))
end

it 'returns object of undesirable class' do
assert_equal(ts.load([]), [])
end
end

describe '.dump(object)' do
let(:default) { 'null' }

it 'is defined' do
assert_respond_to(ts, :dump)
end

it 'handles nil' do
assert_equal(ts.dump(nil), default)
end

it 'handles empty hash' do
assert_equal(ts.dump({}), '{}')
end

it 'deserialize tokens' do
assert_equal(ts.dump(tokens), json)
end

it 'removes nil values' do
new_tokens = tokens.dup
new_tokens[new_tokens.first[0]][:kos] = nil

assert_equal(ts.dump(tokens), ts.dump(new_tokens))
end
end
end
end

0 comments on commit f929fb4

Please sign in to comment.