Last active
July 19, 2016 06:58
-
-
Save rodionovd/4113ed644a078913c606 to your computer and use it in GitHub Desktop.
Revisions
-
rodionovd revised this gist
Jan 26, 2016 . 1 changed file with 3 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -50,14 +50,13 @@ def fetch_secrets(node="start", session) return body["secret"] if body.key? "secret" # It's not a leaf, but a regular node, so go down and ask siblings # for their secrets siblings = body["next"] # Caveat: some nodes have only one sibling which is represented as a # plain string; we wrap it into a single-item array for consistency siblings = Array(siblings) if siblings.is_a? String secrets = siblings.map { |buddy| fetch_secrets(buddy, session) }.join("") return secrets rescue StandardError => e puts "HTTP Request failed: #{e.message}" -
rodionovd revised this gist
Jan 21, 2016 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -64,7 +64,7 @@ def fetch_secrets(node="start", session) end end puts "Fetching the Curbside's secrets. It may take a while, so go grab some coffee ☕️" secrets = fetch_secrets(acquire_session) puts "Got it: \"#{secrets}\"!" -
rodionovd revised this gist
Jan 21, 2016 . 1 changed file with 41 additions and 41 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,58 +10,58 @@ # Due to the nature of this token -- it's valid for 10 requests only -- we'll # call this function more than once. def acquire_session() endpoint = URI('http://challenge.shopcurbside.com/get-session') http = Net::HTTP.new(endpoint.host, endpoint.port) req = Net::HTTP::Get.new(endpoint) return http.request(req).body end # Converts all keys of the given hash to lowercase. def lowecase_hash(hash) result = {} hash.each {|k, v| result.merge!({k.downcase => v}) } return result end # The whole puzzle is a tree: you receive either a node containing URLs # of its sibling nodes or a leaf containing a single secret character. # This function will traverse the tree recursively and fetch all the secrets it # hides. def fetch_secrets(node="start", session) begin uri = URI("http://challenge.shopcurbside.com/#{node}") http = Net::HTTP.new(uri.host, uri.port) req = Net::HTTP::Get.new(uri) req.add_field("Session", session) res = http.request(req) body = JSON.parse(res.body) # In some nodes there're keys with mixed capitalization # (e.g. "neXT" vs "nExt" vs "next"), so here's a workaround body = lowecase_hash(body) # A session token lasts for only 10 requests, and we have to # renew it once in a while if body.key?("error") # TODO(rodionovd): maybe check an actual error msg? return fetch_secrets(node, acquire_session) end # So this's a leaf of the tree and we just pop up a secret value return body["secret"] if body.key? "secret" # It's not a leaf, but a regular node, so go down and ask siblings # for their secrets secrets = "" siblings = body["next"] # Caveat: some nodes have only one sibling which is represented as a # plain string; we wrap it into a single-item array for consistency siblings = Array(siblings) if siblings.is_a? String for buddy in siblings secrets << fetch_secrets(buddy, session) end return secrets rescue StandardError => e puts "HTTP Request failed: #{e.message}" end end puts "Fetching the Curbside's secrets. It may take a while, so go grab some coffie ☕️" -
rodionovd created this gist
Jan 21, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,71 @@ #!/usr/bin/ruby # # (c) Dmitry Rodionov, 2016 # http://internals.exposed require 'net/http' require 'json' # Sends a GET request to /get-session in order to acquire a new session token. # Due to the nature of this token -- it's valid for 10 requests only -- we'll # call this function more than once. def acquire_session() endpoint = URI('http://challenge.shopcurbside.com/get-session') http = Net::HTTP.new(endpoint.host, endpoint.port) req = Net::HTTP::Get.new(endpoint) return http.request(req).body end # Converts all keys of the given hash to lowercase. def lowecase_hash(hash) result = {} hash.each {|k, v| result.merge!({k.downcase => v}) } return result end # The whole puzzle is a tree: you receive either a node containing URLs # of its sibling nodes or a leaf containing a single secret character. # This function will traverse the tree recursively and fetch all the secrets it # hides. def fetch_secrets(node="start", session) begin uri = URI("http://challenge.shopcurbside.com/#{node}") http = Net::HTTP.new(uri.host, uri.port) req = Net::HTTP::Get.new(uri) req.add_field("Session", session) res = http.request(req) body = JSON.parse(res.body) # In some nodes there're keys with mixed capitalization # (e.g. "neXT" vs "nExt" vs "next"), so here's a workaround body = lowecase_hash(body) # A session token lasts for only 10 requests, and we have to # renew it once in a while if body.key?("error") # TODO(rodionovd): maybe check an actual error msg? return fetch_secrets(node, acquire_session) end # So this's a leaf of the tree and we just pop up a secret value return body["secret"] if body.key? "secret" # It's not a leaf, but a regular node, so go down and ask siblings # for their secrets secrets = "" siblings = body["next"] # Caveat: some nodes have only one sibling which is represented as a # plain string; we wrap it into a single-item array for consistency siblings = Array(siblings) if siblings.is_a? String for buddy in siblings secrets << fetch_secrets(buddy, session) end return secrets rescue StandardError => e puts "HTTP Request failed: #{e.message}" end end puts "Fetching the Curbside's secrets. It may take a while, so go grab some coffie ☕️" secrets = fetch_secrets(acquire_session) puts "Got it: \"#{secrets}\"!" # > Apply at systemd@shopcurbside.com with your code