11168: Double-decode serialized fields if database was mangled by downgraded API...
[arvados.git] / services / api / db / migrate / 20140423133559_new_scope_format.rb
1 # At the time we introduced scopes everywhere, VirtualMachinesController
2 # recognized scopes that gave the URL for a VM to grant access to that VM's
3 # login list.  This migration converts those VM-specific scopes to the new
4 # general format, and back.
5
6 class NewScopeFormat < ActiveRecord::Migration
7   include CurrentApiClient
8
9   VM_PATH_REGEX =
10     %r{(/arvados/v1/virtual_machines/[0-9a-z]{5}-[0-9a-z]{5}-[0-9a-z]{15})}
11   OLD_SCOPE_REGEX = %r{^https?://[^/]+#{VM_PATH_REGEX.source}$}
12   NEW_SCOPE_REGEX = %r{^GET #{VM_PATH_REGEX.source}/logins$}
13
14   def fix_scopes_matching(regex)
15     act_as_system_user
16     ApiClientAuthorization.find_each do |auth|
17       auth.scopes = auth.scopes.map do |scope|
18         if match = regex.match(scope)
19           yield match
20         else
21           scope
22         end
23       end
24       auth.save!
25     end
26   end
27
28   def up
29     fix_scopes_matching(OLD_SCOPE_REGEX) do |match|
30       "GET #{match[1]}/logins"
31     end
32   end
33
34   def down
35     case Rails.env
36     when 'test'
37       hostname = 'www.example.com'
38     else
39       require 'socket'
40       hostname = Socket.gethostname
41     end
42     fix_scopes_matching(NEW_SCOPE_REGEX) do |match|
43       Rails.application.routes.url_for(controller: 'virtual_machines',
44                                        uuid: match[1].split('/').last,
45                                        host: hostname, protocol: 'https')
46     end
47   end
48 end