github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/tests/system/lib/move.rb (about) 1 class Move 2 def initialize(source, target) 3 @source = source 4 @target = target 5 end 6 7 def get_initialize_token 8 opts = { 9 max_redirects: 0, 10 cookies: { cozysessid: @source.open_session } 11 } 12 @source.client["/move/initialize"].post(nil, opts) do |response| 13 params = extract_query_string response.headers[:location] 14 @source_client_id = params["client_id"] 15 @source_client_secret = params["client_secret"] 16 @source_token = access_token @source, params 17 end 18 end 19 20 def get_source_token 21 opts = { 22 max_redirects: 0, 23 cookies: { cozysessid: @source.open_session } 24 } 25 state = "123456789" 26 qs = "state=#{state}&redirect_uri=#{redirect_uri}" 27 @source.client["/move/authorize?#{qs}"].get(opts) do |response| 28 params = extract_query_string response.headers[:location] 29 @code = params["code"] 30 end 31 end 32 33 def get_target_token 34 client = create_oauth_client @target 35 @target_client_id = client["client_id"] 36 @target_client_secret = client["client_secret"] 37 38 state = "123456789" 39 opts = { accept: "application/json", cookies: { cozysessid: @source.open_session } } 40 qs = "state=#{state}&client_id=#{@target_client_id}&redirect_uri=#{redirect_uri}" 41 res = @target.client["/auth/authorize/move?#{qs}"].get opts 42 csrf_token = res.cookies["_csrf"] 43 44 body = { 45 state: state, 46 client_id: @target_client_id, 47 csrf_token: csrf_token, 48 redirect_uri: redirect_uri, 49 passphrase: @target.hashed_passphrase 50 } 51 opts[:cookies] = res.cookies 52 res = @target.client["/auth/authorize/move"].post(body, opts) 53 redirect = JSON.parse(res.body)["redirect"] 54 params = extract_query_string redirect 55 @target_token = access_token @target, params.merge(client) 56 end 57 58 def create_oauth_client(inst) 59 params = { 60 client_name: "Cozy-Move", 61 client_kind: "web", 62 client_uri: "http://localhost:4000/", 63 redirect_uris: [redirect_uri], 64 software_id: "github.com/cozy/cozy-move", 65 software_version: "0.0.1" 66 } 67 body = JSON.generate(params) 68 opts = { accept: "application/json", "Content-Type": "application/json" } 69 res = inst.client["/auth/register"].post body, opts 70 JSON.parse(res.body) 71 end 72 73 def redirect_uri 74 "http://localhost:4000/callback/target" 75 end 76 77 def access_token(inst, params) 78 body = { 79 grant_type: "authorization_code", 80 code: params["code"], 81 client_id: params["client_id"], 82 client_secret: params["client_secret"] 83 } 84 opts = { accept: :json } 85 res = inst.client["/auth/access_token"].post body, opts 86 JSON.parse(res.body)["access_token"] 87 end 88 89 def extract_query_string(location) 90 query = URI.parse(location).query 91 CGI.parse(query).inject({}) do |h, (k, v)| 92 h[k] = v.first 93 h 94 end 95 end 96 97 def run 98 body = { 99 target_url: @target.url, 100 target_token: @target_token, 101 target_client_id: @target_client_id, 102 target_client_secret: @target_client_secret 103 } 104 if @code 105 body[:code] = @code 106 else 107 body[:token] = @source_token 108 body[:client_id] = @source_client_id 109 body[:client_secret] = @source_client_secret 110 end 111 opts = { accept: "*/*" } 112 @source.client["/move/request"].post body, opts 113 end 114 115 def confirm(timeout = 120) 116 timeout.times do 117 sleep 1 118 received = Email.received kind: "to", query: @source.email 119 received.reject! { |e| e.subject =~ /(New.connection|Nouvelle.connexion)/ } 120 return confirm_mail received.first if received.any? 121 end 122 raise "Confirmation mail for moving was not received after #{timeout} seconds" 123 end 124 125 def confirm_mail(mail) 126 scanned = mail.body.scan(/secret=3D(\w+)/) 127 raise "No secret in #{mail.subject} - #{mail.body}" if scanned.empty? 128 secret = scanned.last.last 129 opts = { cookies: { cozysessid: @source.open_session } } 130 @source.client["/move/go?secret=#{secret}"].get opts 131 end 132 133 def wait_done(timeout = 120) 134 timeout.times do 135 sleep 1 136 received = Email.received kind: "to", query: @target.email 137 return if received.any? 138 end 139 raise "Moved mail was not received after #{timeout} seconds" 140 end 141 end