parent
fca1da6897
commit
f125788b68
@ -0,0 +1,250 @@ |
||||
desc "Anonymize your database -- DON'T USE THIS UNLESS YOU REALLY, REALLY KNOW WHAT YOU'RE DOING. NOT KIDDING HERE!" |
||||
|
||||
$LOREM = " |
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer in |
||||
mi a mauris ornare sagittis. Suspendisse potenti. Suspendisse dapibus |
||||
dignissim dolor. Nam sapien tellus, tempus et, tempus ac, tincidunt |
||||
in, arcu. Duis dictum. Proin magna nulla, pellentesque non, commodo |
||||
et, iaculis sit amet, mi. Mauris condimentum massa ut metus. Donec |
||||
viverra, sapien mattis rutrum tristique, lacus eros semper tellus, et |
||||
molestie nisi sapien eu massa. Vestibulum ante ipsum primis in |
||||
faucibus orci luctus et ultrices posuere cubilia Curae; Fusce erat |
||||
tortor, mollis ut, accumsan ut, lacinia gravida, libero. Curabitur |
||||
massa felis, accumsan feugiat, convallis sit amet, porta vel, neque. |
||||
Duis et ligula non elit ultricies rutrum. Suspendisse tempor. |
||||
Quisque posuere malesuada velit. Sed pellentesque mi a purus. Integer |
||||
imperdiet, orci a eleifend mollis, velit nulla iaculis arcu, eu rutrum |
||||
magna quam sed elit. Nullam egestas. Integer interdum purus nec |
||||
mauris. Vestibulum ac mi in nunc suscipit dapibus. Duis consectetuer, |
||||
ipsum et pharetra sollicitudin, metus turpis facilisis magna, vitae |
||||
dictum ligula nulla nec mi. Nunc ante urna, gravida sit amet, congue |
||||
et, accumsan vitae, magna. Praesent luctus. Nullam in velit. Praesent |
||||
est. Curabitur turpis. |
||||
Class aptent taciti sociosqu ad litora torquent per conubia nostra, |
||||
per inceptos hymenaeos. Cras consectetuer, nibh in lacinia ornare, |
||||
turpis sem tempor massa, sagittis feugiat mauris nibh non tellus. |
||||
Phasellus mi. Fusce enim. Mauris ultrices, turpis eu adipiscing |
||||
viverra, justo libero ullamcorper massa, id ultrices velit est quis |
||||
tortor. Quisque condimentum, lacus volutpat nonummy accumsan, est nunc |
||||
imperdiet magna, vulputate aliquet nisi risus at est. Aliquam |
||||
imperdiet gravida tortor. Praesent interdum accumsan ante. Vivamus est |
||||
ligula, consequat sed, pulvinar eu, consequat vitae, eros. Nulla elit |
||||
nunc, congue eget, scelerisque a, tempor ac, nisi. Morbi facilisis. |
||||
Pellentesque habitant morbi tristique senectus et netus et malesuada |
||||
fames ac turpis egestas. In hac habitasse platea dictumst. Suspendisse |
||||
vel lorem ut ligula tempor consequat. Quisque consectetuer nisl eget |
||||
elit. |
||||
Proin quis mauris ac orci accumsan suscipit. Sed ipsum. Sed vel libero |
||||
nec elit feugiat blandit. Vestibulum purus nulla, accumsan et, |
||||
volutpat at, pellentesque vel, urna. Suspendisse nonummy. Aliquam |
||||
pulvinar libero. Donec vulputate, orci ornare bibendum condimentum, |
||||
lorem elit dignissim sapien, ut aliquam nibh augue in turpis. |
||||
Phasellus ac eros. Praesent luctus, lorem a mollis lacinia, leo turpis |
||||
commodo sem, in lacinia mi quam et quam. Curabitur a libero vel tellus |
||||
mattis imperdiet. In congue, neque ut scelerisque bibendum, libero |
||||
lacus ullamcorper sapien, quis aliquet massa velit vel orci. Fusce in |
||||
nulla quis est cursus gravida. In nibh. Lorem ipsum dolor sit amet, |
||||
consectetuer adipiscing elit. Integer fermentum pretium massa. Morbi |
||||
feugiat iaculis nunc. |
||||
Aenean aliquam pretium orci. Cum sociis natoque penatibus et magnis |
||||
dis parturient montes, nascetur ridiculus mus. Vivamus quis tellus vel |
||||
quam varius bibendum. Fusce est metus, feugiat at, porttitor et, |
||||
cursus quis, pede. Nam ut augue. Nulla posuere. Phasellus at dolor a |
||||
enim cursus vestibulum. Duis id nisi. Duis semper tellus ac nulla. |
||||
Vestibulum scelerisque lobortis dolor. Aenean a felis. Aliquam erat |
||||
volutpat. Donec a magna vitae pede sagittis lacinia. Cras vestibulum |
||||
diam ut arcu. Mauris a nunc. Duis sollicitudin erat sit amet turpis. |
||||
Proin at libero eu diam lobortis fermentum. Nunc lorem turpis, |
||||
imperdiet id, gravida eget, aliquet sed, purus. Ut vehicula laoreet |
||||
ante. |
||||
Mauris eu nunc. Sed sit amet elit nec ipsum aliquam egestas. Donec non |
||||
nibh. Cras sodales pretium massa. Praesent hendrerit est et risus. |
||||
Vivamus eget pede. Curabitur tristique scelerisque dui. Nullam |
||||
ullamcorper. Vivamus venenatis velit eget enim. Nunc eu nunc eget |
||||
felis malesuada fermentum. Quisque magna. Mauris ligula felis, luctus |
||||
a, aliquet nec, vulputate eget, magna. Quisque placerat diam sed arcu. |
||||
Praesent sollicitudin. Aliquam non sapien. Quisque id augue. Class |
||||
aptent taciti sociosqu ad litora torquent per conubia nostra, per |
||||
inceptos hymenaeos. Etiam lacus lectus, mollis quis, mattis nec, |
||||
commodo facilisis, nibh. Sed sodales sapien ac ante. Duis eget lectus |
||||
in nibh lacinia auctor. |
||||
Fusce interdum lectus non dui. Integer accumsan. Quisque quam. |
||||
Curabitur scelerisque imperdiet nisl. Suspendisse potenti. Nam massa |
||||
leo, iaculis sed, accumsan id, ultrices nec, velit. Suspendisse |
||||
potenti. Mauris bibendum, turpis ac viverra sollicitudin, metus massa |
||||
interdum orci, non imperdiet orci ante at ipsum. Etiam eget magna. |
||||
Mauris at tortor eu lectus tempor tincidunt. Phasellus justo purus, |
||||
pharetra ut, ultricies nec, consequat vel, nisi. Fusce vitae velit at |
||||
libero sollicitudin sodales. Aenean mi libero, ultrices id, suscipit |
||||
vitae, dapibus eu, metus. Aenean vestibulum nibh ac massa. Vivamus |
||||
vestibulum libero vitae purus. In hac habitasse platea dictumst. |
||||
Curabitur blandit nunc non arcu. |
||||
Ut nec nibh. Morbi quis leo vel magna commodo rhoncus. Donec congue |
||||
leo eu lacus. Pellentesque at erat id mi consequat congue. Praesent a |
||||
nisl ut diam interdum molestie. Fusce suscipit rhoncus sem. Donec |
||||
pretium. Aliquam molestie. Vivamus et justo at augue aliquet dapibus. |
||||
Pellentesque felis. |
||||
Morbi semper. In venenatis imperdiet neque. Donec auctor molestie |
||||
augue. Nulla id arcu sit amet dui lacinia convallis. Proin tincidunt. |
||||
Proin a ante. Nunc imperdiet augue. Nullam sit amet arcu. Quisque |
||||
laoreet viverra felis. Lorem ipsum dolor sit amet, consectetuer |
||||
adipiscing elit. In hac habitasse platea dictumst. Pellentesque |
||||
habitant morbi tristique senectus et netus et malesuada fames ac |
||||
turpis egestas. Class aptent taciti sociosqu ad litora torquent per |
||||
conubia nostra, per inceptos hymenaeos. Nullam nibh sapien, volutpat |
||||
ut, placerat quis, ornare at, lorem. Class aptent taciti sociosqu ad |
||||
litora torquent per conubia nostra, per inceptos hymenaeos. |
||||
Morbi dictum massa id libero. Ut neque. Phasellus tincidunt, nibh ut |
||||
tincidunt lacinia, lacus nulla aliquam mi, a interdum dui augue non |
||||
pede. Duis nunc magna, vulputate a, porta at, tincidunt a, nulla. |
||||
Praesent facilisis. Suspendisse sodales feugiat purus. Cras et justo a |
||||
mauris mollis imperdiet. Morbi erat mi, ultrices eget, aliquam |
||||
elementum, iaculis id, velit. In scelerisque enim sit amet turpis. Sed |
||||
aliquam, odio nonummy ullamcorper mollis, lacus nibh tempor dolor, sit |
||||
amet varius sem neque ac dui. Nunc et est eu massa eleifend mollis. |
||||
Mauris aliquet orci quis tellus. Ut mattis. |
||||
Praesent mollis consectetuer quam. Nulla nulla. Nunc accumsan, nunc |
||||
sit amet scelerisque porttitor, nibh pede lacinia justo, tristique |
||||
mattis purus eros non velit. Aenean sagittis commodo erat. Aliquam id |
||||
lacus. Morbi vulputate vestibulum elit." |
||||
$LOREM = $LOREM.gsub(/\s+/, ' ') |
||||
$LOREM = $LOREM.split(/[.]\s*/) |
||||
|
||||
def lorem(n) |
||||
return $LOREM[rand($LOREM.size - 20)..-1].join('. ')[0, n] |
||||
end |
||||
|
||||
$ALPHANUMERICS = [('0'..'9'),('A'..'Z'),('a'..'z')].map {|range| range.to_a}.flatten |
||||
$RANDOM_CACHE = ((0... 100).map { $ALPHANUMERICS[rand($ALPHANUMERICS.size)] }.join) |
||||
$PASSWORD = ((0... 8).map { $ALPHANUMERICS[rand($ALPHANUMERICS.size)] }.join) |
||||
|
||||
$UNIQUE = [ |
||||
'IssuePriority#name', |
||||
'ActsAsTaggableOn::Tag#name', |
||||
'Version#name', |
||||
'IssueStatus#name' |
||||
] |
||||
|
||||
$UNIQUE = {} |
||||
|
||||
def unique(model_attr) |
||||
v = $UNIQUE[model_attr].to_i + 1 |
||||
$UNIQUE[model_attr] = v |
||||
|
||||
v = "#{model_attr.split('#')[0]}#{v}" |
||||
v << "@example.com" if model_attr.match(/#mail/) |
||||
|
||||
return v |
||||
end |
||||
|
||||
def random_string(model_attr, v) |
||||
return nil if !v |
||||
|
||||
return $PASSWORD if model_attr.match(/#password$/) |
||||
|
||||
# these are required to be unique |
||||
return unique(model_attr) if $UNIQUE.include?(model_attr) || model_attr.match(/#mail$/) |
||||
|
||||
return lorem(v.size) if v.match(/ /) |
||||
|
||||
nv = nil |
||||
l = v.size |
||||
|
||||
while nv.nil? |
||||
start = rand($RANDOM_CACHE.size / 3) |
||||
|
||||
if $RANDOM_CACHE.size >= start + l |
||||
nv = $RANDOM_CACHE[start, l] |
||||
else |
||||
$RANDOM_CACHE << ((0... (l * 3)).map { $ALPHANUMERICS[rand($ALPHANUMERICS.size)] }.join) |
||||
end |
||||
end |
||||
|
||||
return nv |
||||
end |
||||
|
||||
|
||||
namespace :redmine do |
||||
namespace :backlogs_plugin do |
||||
task :anonymize => :environment do |
||||
puts "This will anonymize ALL YOUR DATA" |
||||
puts "ARE YOU VERY, VERY SURE?" |
||||
puts "If so, type 'Yes!' (case matters!)" |
||||
|
||||
answer = STDIN.gets.chomp |
||||
return if answer != "Yes!" |
||||
|
||||
ignore = [ |
||||
'AnonymousUser#language', |
||||
'Version#status', |
||||
'Version#sharing', |
||||
'CustomField#regexp', |
||||
'CustomField#field_format', |
||||
'Principal#language', |
||||
'JournalDetail#property', |
||||
'JournalDetail#prop_key', |
||||
'Query#column_names', |
||||
'Query#group_by', |
||||
'Query#sort_criteria', |
||||
'Query#filters', |
||||
'Enumeration#name', |
||||
'WikiContent::Version#compression', |
||||
'User#language', |
||||
'AnonymousUser#login', |
||||
] |
||||
|
||||
admins = [] |
||||
ActiveRecord::Base.send(:subclasses).each do |model| |
||||
attrs = {} |
||||
model.columns_hash.each_pair { |attrib, column| |
||||
#next unless model.content_columns.include?(column) |
||||
next if column.name == 'type' |
||||
next if attrib.match(/_type$/) |
||||
next if [:integer, :boolean, :datetime, :date, :float].include?(column.type) |
||||
next if ignore.include?("#{model.name}##{attrib}") |
||||
|
||||
attrib = 'password' if attrib == 'hashed_password' |
||||
|
||||
attrs[attrib] = nil |
||||
} |
||||
|
||||
if attrs.size != 0 |
||||
puts "Anonymizing #{model.name} ..." |
||||
model.all.each { |obj| |
||||
save_error = nil |
||||
10.times do |attempt| |
||||
attrs.each_pair {|k, v| |
||||
attrs[k] = random_string("#{model.name}##{k}", obj.send(k)) |
||||
} |
||||
|
||||
attempt_string = (attempt == 0 ? '' : " (attempt #{attempt + 1}") |
||||
|
||||
puts "... #{model.name} #{obj.id}#{attempt_string}" |
||||
|
||||
begin |
||||
obj.update_attributes(attrs) |
||||
obj.save! |
||||
save_error = nil |
||||
break |
||||
rescue ActiveRecord::RecordInvalid => save_error |
||||
end |
||||
end |
||||
|
||||
raise "Not able to save #{model.name} #{obj.id}: #{save_error}" if save_error |
||||
|
||||
if model.name == 'User' && obj.admin? |
||||
admins << obj.login |
||||
end |
||||
} |
||||
end |
||||
end |
||||
|
||||
User.find(:all).each { |user| |
||||
user.password = $PASSWORD |
||||
user.save! |
||||
} |
||||
|
||||
puts "Your anonymized admins are #{admins.inspect} with password '#{$PASSWORD}'" |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue