1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
5 require 'current_api_client'
7 # This is needed instead of just including CurrentApiClient so that its
8 # methods don't get imported as Object's class methods; this is a problem because
9 # the methods would be imported only on test environment. See #15716 for more info.
10 class CurrentApiClientHelper
11 extend CurrentApiClient
17 return true if has_symbols?(k) or has_symbols?(v)
21 return true if has_symbols?(k)
26 return true if x.start_with?(':') && !x.start_with?('::')
31 def check_for_serialized_symbols rec
32 jsonb_cols = rec.class.columns.select{|c| c.type == :jsonb}.collect{|j| j.name}
33 (jsonb_cols + rec.class.serialized_attributes.keys).uniq.each do |colname|
34 if has_symbols? rec.attributes[colname]
35 st = recursive_stringify rec.attributes[colname]
36 puts "Found value potentially containing Ruby symbols in #{colname} attribute of #{rec.uuid}, current value is\n#{rec.attributes[colname].to_s[0..1024]}\nrake symbols:stringify will update it to:\n#{st.to_s[0..1024]}\n\n"
41 def recursive_stringify x
43 Hash[x.collect do |k,v|
44 [recursive_stringify(k), recursive_stringify(v)]
52 elsif x.is_a? String and x.start_with?(':') and !x.start_with?('::')
59 def stringify_serialized_symbols rec
60 # ensure_serialized_attribute_type should prevent symbols from
61 # getting into the database in the first place. If someone managed
62 # to get them into the database (perhaps using an older version)
63 # we'll convert symbols to strings when loading from the
64 # database. (Otherwise, loading and saving an object with existing
65 # symbols in a serialized field will crash.)
66 jsonb_cols = rec.class.columns.select{|c| c.type == :jsonb}.collect{|j| j.name}
67 (jsonb_cols + rec.class.serialized_attributes.keys).uniq.each do |colname|
68 if has_symbols? rec.attributes[colname]
70 st = recursive_stringify rec.attributes[colname]
71 puts "Updating #{colname} attribute of #{rec.uuid} from\n#{rec.attributes[colname].to_s[0..1024]}\nto\n#{st.to_s[0..1024]}\n\n"
72 rec.write_attribute(colname, st)
75 puts "Failed to update #{rec.uuid}: #{e}"
82 desc 'Warn about serialized values starting with ":" that may be symbols'
83 task check: :environment do
84 [ApiClientAuthorization, ApiClient,
85 AuthorizedKey, Collection,
86 Container, ContainerRequest, Group,
87 Human, Job, JobTask, KeepDisk, KeepService, Link,
88 Node, PipelineInstance, PipelineTemplate,
89 Repository, Specimen, Trait, User, VirtualMachine,
90 Workflow].each do |klass|
91 CurrentApiClientHelper.act_as_system_user do
93 check_for_serialized_symbols c
99 task stringify: :environment do
100 [ApiClientAuthorization, ApiClient,
101 AuthorizedKey, Collection,
102 Container, ContainerRequest, Group,
103 Human, Job, JobTask, KeepDisk, KeepService, Link,
104 Node, PipelineInstance, PipelineTemplate,
105 Repository, Specimen, Trait, User, VirtualMachine,
106 Workflow].each do |klass|
107 CurrentApiClientHelper.act_as_system_user do
108 klass.all.each do |c|
109 stringify_serialized_symbols c