1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
5 require 'current_api_client'
7 include CurrentApiClient
12 return true if has_symbols?(k) or has_symbols?(v)
16 return true if has_symbols?(k)
21 return true if x.start_with?(':') && !x.start_with?('::')
26 def check_for_serialized_symbols rec
27 jsonb_cols = rec.class.columns.select{|c| c.type == :jsonb}.collect{|j| j.name}
28 (jsonb_cols + rec.class.serialized_attributes.keys).uniq.each do |colname|
29 if has_symbols? rec.attributes[colname]
30 st = recursive_stringify rec.attributes[colname]
31 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"
36 def recursive_stringify x
38 Hash[x.collect do |k,v|
39 [recursive_stringify(k), recursive_stringify(v)]
47 elsif x.is_a? String and x.start_with?(':') and !x.start_with?('::')
54 def stringify_serialized_symbols rec
55 # ensure_serialized_attribute_type should prevent symbols from
56 # getting into the database in the first place. If someone managed
57 # to get them into the database (perhaps using an older version)
58 # we'll convert symbols to strings when loading from the
59 # database. (Otherwise, loading and saving an object with existing
60 # symbols in a serialized field will crash.)
61 jsonb_cols = rec.class.columns.select{|c| c.type == :jsonb}.collect{|j| j.name}
62 (jsonb_cols + rec.class.serialized_attributes.keys).uniq.each do |colname|
63 if has_symbols? rec.attributes[colname]
65 st = recursive_stringify rec.attributes[colname]
66 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"
67 rec.write_attribute(colname, st)
70 puts "Failed to update #{rec.uuid}: #{e}"
77 desc 'Warn about serialized values starting with ":" that may be symbols'
78 task check: :environment do
79 [ApiClientAuthorization, ApiClient,
80 AuthorizedKey, Collection,
81 Container, ContainerRequest, Group,
82 Human, Job, JobTask, KeepDisk, KeepService, Link,
83 Node, PipelineInstance, PipelineTemplate,
84 Repository, Specimen, Trait, User, VirtualMachine,
85 Workflow].each do |klass|
88 check_for_serialized_symbols c
94 task stringify: :environment do
95 [ApiClientAuthorization, ApiClient,
96 AuthorizedKey, Collection,
97 Container, ContainerRequest, Group,
98 Human, Job, JobTask, KeepDisk, KeepService, Link,
99 Node, PipelineInstance, PipelineTemplate,
100 Repository, Specimen, Trait, User, VirtualMachine,
101 Workflow].each do |klass|
102 act_as_system_user do
103 klass.all.each do |c|
104 stringify_serialized_symbols c