another_place 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/another_place/application/app.rb +90 -94
- data/lib/another_place/application/evidence.rb +158 -0
- metadata +5 -3
- data/lib/another_place/application/clues.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a18ba075539360c0935c28a56e9f8734f615c453
|
4
|
+
data.tar.gz: 71b653fea957611e6596e4a95a469a8f51bd6782
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ab953a07e07b553de38babde0ec6f6eadde2b151aa1bd22a9ca08ac5be1aad6644db1968d5a3618988cc2b92274d9245312edd841121aa9f7a1e8c33e9655b1
|
7
|
+
data.tar.gz: 33851204dba3cf8522d0d3f30bd9aa36343b3e3e16d10d5d45fe491a1a8dbeda0b3e2687dcdc1543f7666c2ecc15b5e1349e38d4a756ae5c49c691998f4ea0a5
|
@@ -1,144 +1,140 @@
|
|
1
1
|
require 'sinatra'
|
2
2
|
require 'json'
|
3
3
|
|
4
|
-
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
require_relative 'evidence'
|
5
7
|
|
6
8
|
class AnotherPlace < Sinatra::Base
|
9
|
+
# set up our application's configuration
|
10
|
+
configure do
|
11
|
+
enable :logging
|
12
|
+
end
|
7
13
|
|
14
|
+
# set specific configurations to run before each request is handled
|
8
15
|
before do
|
16
|
+
logger.datetime_format = ''
|
9
17
|
headers({"Content-Type" => "application/json"})
|
10
18
|
end
|
11
19
|
|
12
20
|
get '/' do
|
13
21
|
status 200
|
14
|
-
|
15
|
-
body("psst. **Check the headers**")
|
16
|
-
end
|
17
|
-
|
18
|
-
get '/pies' do
|
19
|
-
headers({
|
20
|
-
"X-Clue" => "last character in every value in the hash"
|
21
|
-
})
|
22
|
-
body({
|
23
|
-
sushi: "tuna",
|
24
|
-
spice_level: "XX",
|
25
|
-
test: "IQ",
|
26
|
-
insect: "bug",
|
27
|
-
missing: "vitamin: d",
|
28
|
-
nosebleeds: "2",
|
29
|
-
nickname: "BIFF",
|
30
|
-
trailer: "zardoz"
|
31
|
-
}.to_json)
|
22
|
+
body("::psst:: *check the headers, watch the logs...*\n")
|
32
23
|
end
|
33
24
|
|
34
|
-
get
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
get("/coffee") do
|
39
|
-
headers({"X-Hey-you" => "Come back here and ask for your coffee black"})
|
40
|
-
if params[:black] || params[:type]
|
41
|
-
headers({"X-Clue" => "first character of every key in every hash in the array"})
|
42
|
-
body([
|
43
|
-
{"cardians" => "nina", "Gwar" => "dave"},
|
44
|
-
{"ozma" => "ryen"},
|
45
|
-
{"=w=" => "rivers"}
|
46
|
-
].to_json)
|
47
|
-
end
|
25
|
+
get '/double_r_diner' do
|
26
|
+
# STEP 1
|
27
|
+
logger.info(Evidence::CLUES[request.path][:log_clue])
|
48
28
|
end
|
49
29
|
|
50
|
-
get
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
get("/ladies") do
|
55
|
-
headers({"X-Hey-you" => "If I had a type I'd say it's log ladies"})
|
56
|
-
if params[:type] == "log ladies"
|
30
|
+
get '/pies' do
|
31
|
+
if params[:kind] == 'cherry'
|
32
|
+
# STEP 3
|
33
|
+
logger.info(Evidence::CLUES[request.path][1][:log_clue])
|
57
34
|
headers({
|
58
|
-
"X-Clue" =>
|
35
|
+
"X-Clue" => Evidence::CLUES[request.path][1][:header_clue]
|
59
36
|
})
|
60
|
-
body([
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
get("/aW4gdGhl") do
|
65
|
-
redirect to("/meditations")
|
66
|
-
end
|
67
|
-
|
68
|
-
get("/meditations") do
|
69
|
-
headers({"X-Hey-You" => "Your eyes should be shut"})
|
70
|
-
if params[:eyes] == "shut"
|
37
|
+
body(Evidence::CLUES[request.path][1][:body_clue].to_json)
|
38
|
+
else
|
39
|
+
# STEP 2
|
71
40
|
headers({
|
72
|
-
"X-Clue" =>
|
41
|
+
"X-Clue" => Evidence::CLUES[request.path][0][:header_clue]
|
73
42
|
})
|
74
|
-
body([
|
43
|
+
body(Evidence::CLUES[request.path][0][:body_clue])
|
75
44
|
end
|
76
45
|
end
|
77
46
|
|
78
|
-
get
|
79
|
-
|
47
|
+
get '/scenes/:scene' do
|
48
|
+
if params[:scene] == 'crime'
|
49
|
+
if params[:investigate] == 'body'
|
50
|
+
# STEP 4
|
51
|
+
logger.info(Evidence::CLUES[request.path][:log_clue])
|
52
|
+
redirect to("/aXQgd2FzIHBq", headers({"Content-Transfer-Encoding" => 'base64'}))
|
53
|
+
else
|
54
|
+
logger.info("Right place... What do you want to *investigate*?")
|
55
|
+
end
|
56
|
+
else
|
57
|
+
logger.info("Wrong scene... What are you here to investigate?")
|
58
|
+
end
|
80
59
|
end
|
81
60
|
|
82
|
-
get
|
83
|
-
|
61
|
+
get '/aXQgd2FzIHBq' do
|
62
|
+
# STEP 5
|
63
|
+
logger.info(Evidence::CLUES[request.path][:log_clue])
|
64
|
+
headers({
|
65
|
+
"X-Clue" => Evidence::CLUES[request.path][:header_clue],
|
66
|
+
"Content-Transfer-Encoding" => 'base64'
|
67
|
+
})
|
68
|
+
body(Evidence::CLUES[request.path][:body_clue].to_json)
|
84
69
|
end
|
85
70
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
71
|
+
get '/aW4gdGhlIHJvb3QgZGlyZWN0b3J5' do
|
72
|
+
# STEP 6
|
73
|
+
logger.info(Evidence::CLUES[request.path][:log_clue])
|
74
|
+
headers({
|
75
|
+
"X-Clue" => Evidence::CLUES[request.path][:header_clue]
|
76
|
+
})
|
77
|
+
body(Evidence::CLUES[request.path][:body_clue])
|
93
78
|
end
|
94
79
|
|
95
|
-
get
|
96
|
-
|
80
|
+
get '/alarm' do
|
81
|
+
# STEP 7.1
|
82
|
+
logger.info(Evidence::CLUES[request.path][0][:log_clue])
|
83
|
+
headers({
|
84
|
+
"X-Clue" => Evidence::CLUES[request.path][0][:header_clue]
|
85
|
+
})
|
86
|
+
body(Evidence::CLUES[request.path][0][:body_clue])
|
97
87
|
end
|
98
88
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
{:id => 5, name: "rich's restaurant"},
|
107
|
-
{:id => 6, name: "rr diner"},
|
108
|
-
].to_json)
|
89
|
+
delete '/alarm' do
|
90
|
+
# STEP 7.2
|
91
|
+
logger.info(Evidence::CLUES[request.path][1][:log_clue])
|
92
|
+
headers({
|
93
|
+
"X-Clue" => Evidence::CLUES[request.path][1][:header_clue]
|
94
|
+
})
|
95
|
+
body(Evidence::CLUES[request.path][1][:body_clue])
|
109
96
|
end
|
110
97
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
98
|
+
put '/coffee' do
|
99
|
+
# STEP 8
|
100
|
+
if params[:extra].include?("sugar") && params[:extra].include?("cream")
|
101
|
+
logger.info(Evidence::CLUES[request.path][:log_clue])
|
102
|
+
headers({
|
103
|
+
"X-Clue" => Evidence::CLUES[request.path][:header_clue]
|
104
|
+
})
|
105
|
+
body(Evidence::CLUES[request.path][:body_clue].to_json)
|
106
|
+
else
|
107
|
+
logger.info("Send the data: {'extra' => ['sugar','cream']}...")
|
116
108
|
end
|
117
109
|
end
|
118
110
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
if params[:gums] == "news" && params[:in_style]
|
125
|
-
redirect to("/another_place")
|
111
|
+
post '/police' do
|
112
|
+
# STEP 9.1
|
113
|
+
if params[:clue] == 'it_was_all_a_dream'
|
114
|
+
logger.info(Evidence::CLUES[request.path][0][:log_clue])
|
115
|
+
redirect to('/police', headers({"X-Clue" => Evidence::CLUES[request.path][0][:header_clue]}))
|
126
116
|
end
|
127
117
|
end
|
128
118
|
|
129
|
-
get
|
119
|
+
get '/police' do
|
120
|
+
# STEP 9.2
|
121
|
+
logger.info(Evidence::CLUES[request.path][1][:log_clue])
|
130
122
|
headers({
|
131
|
-
"X-
|
123
|
+
"X-Clue" => Evidence::CLUES[request.path][1][:header_clue]
|
132
124
|
})
|
133
|
-
body("cm0gLXJm")
|
134
125
|
end
|
135
126
|
|
136
|
-
get
|
137
|
-
|
127
|
+
get '/another_place' do
|
128
|
+
# STEP 10
|
129
|
+
|
138
130
|
end
|
131
|
+
|
132
|
+
|
139
133
|
end
|
140
134
|
|
141
135
|
# Run the app!
|
142
136
|
#
|
143
137
|
puts "Starting a server in another place."
|
138
|
+
Evidence.print_to_log Evidence::START_MESSAGE
|
139
|
+
|
144
140
|
AnotherPlace.run!
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module Evidence
|
2
|
+
|
3
|
+
def self.print_to_log(message)
|
4
|
+
$stderr.puts "== #{message}"
|
5
|
+
end
|
6
|
+
|
7
|
+
START_MESSAGE = <<EOF
|
8
|
+
|
9
|
+
Welcome to the town of Palmer Lakes, officer. It's a sleepy place:
|
10
|
+
we've never quite seen something like this before... Sorry you had
|
11
|
+
to come out for such a tragedy. But where are my manners? Let's
|
12
|
+
head over to the double_r_diner and get some cherry pie. Plus,
|
13
|
+
they make a damn fine coffee!
|
14
|
+
|
15
|
+
> As with all of the clues here, you'll have to identify an API
|
16
|
+
> endpoint and the correctly formatted URL and HTTP request verb
|
17
|
+
> to access the next clue.
|
18
|
+
>
|
19
|
+
> You can use HTTParty, Postman, or `curl url:port --include` to
|
20
|
+
> inspect the HTTP response's header AND body.
|
21
|
+
>
|
22
|
+
> Let's start by getting "/double_r_diner"...
|
23
|
+
==
|
24
|
+
EOF
|
25
|
+
|
26
|
+
# header
|
27
|
+
# puzzle
|
28
|
+
# query
|
29
|
+
# puzzle
|
30
|
+
# data
|
31
|
+
# puzzle
|
32
|
+
|
33
|
+
# "/path" => {
|
34
|
+
# header_clue: ,
|
35
|
+
# log_clue: ,
|
36
|
+
# body_clue:
|
37
|
+
# },
|
38
|
+
|
39
|
+
CLUES = {
|
40
|
+
"/double_r_diner" => {
|
41
|
+
header_clue: "",
|
42
|
+
log_clue: "Take a look at all our /pies... Find one you want?",
|
43
|
+
body_clue: ""
|
44
|
+
},
|
45
|
+
"/pies" => [
|
46
|
+
{
|
47
|
+
header_clue: "What **kind** of pie do you want? Try asking for it with a query?",
|
48
|
+
log_clue: "",
|
49
|
+
body_clue: "\"That is a fantastic-looking **cherry** pie!\"\n"
|
50
|
+
},
|
51
|
+
{
|
52
|
+
header_clue: "What should we do next? Where should we go?",
|
53
|
+
log_clue: "You will need to use both a nested path (resource/id) and a query parameter...",
|
54
|
+
body_clue: {
|
55
|
+
resource: 'scenes',
|
56
|
+
resource_id: 'crime',
|
57
|
+
query: {investigate: 'body'}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
],
|
61
|
+
"/scenes/crime" => {
|
62
|
+
header_clue: "",
|
63
|
+
log_clue: "Trust your instincts. Follow the status code, and do what it asks of you.",
|
64
|
+
body_clue: ""
|
65
|
+
},
|
66
|
+
"/aXQgd2FzIHBq" => {
|
67
|
+
header_clue: "Join all of the odd elements, after the array has been reversed",
|
68
|
+
log_clue: "You are now in *another place*... Is this a dream???",
|
69
|
+
body_clue: [
|
70
|
+
"5", "3os", "b3J", "3HH", "WN0", "hwq", "lyZ", "sPk", "gZG", "e00",
|
71
|
+
"b3Q", "9F.", "HJv", "bky", "hlI", "8fh", "gdG", "2he", "aW4", "111"
|
72
|
+
]
|
73
|
+
},
|
74
|
+
"/aW4gdGhlIHJvb3QgZGlyZWN0b3J5" => {
|
75
|
+
header_clue: "You hear something... Could it be an /alarm ?",
|
76
|
+
log_clue: "Wake up!",
|
77
|
+
body_clue: "::beep:: ::beep:: ::beep:: ::beep::\n"
|
78
|
+
},
|
79
|
+
"/alarm" => [
|
80
|
+
{
|
81
|
+
header_clue: "THE ALARM IS STILL ON! REMOVE THIS RESOURCE!",
|
82
|
+
log_clue: "To remove a resource, we need to **DELETE** it... We need more REST!",
|
83
|
+
body_clue: "::beep:: ::beep:: ::beep:: ::beep::\n"
|
84
|
+
},
|
85
|
+
{
|
86
|
+
header_clue: "I need some /coffee... But this coffee is black.",
|
87
|
+
log_clue: "Let's **PUT** something **extra** into the coffee, like [**sugar**, **cream**].",
|
88
|
+
body_clue: "Structuring this data may be odd... HTTParty may be best to send it."
|
89
|
+
}
|
90
|
+
],
|
91
|
+
"/coffee" => {
|
92
|
+
header_clue: "Wait a minute, I think I have it... We need to call the /police and leave them a message!",
|
93
|
+
log_clue: "Let's send the police the clue below to tell them what we know.",
|
94
|
+
body_clue: {
|
95
|
+
clue: "it_was_all_a_dream"
|
96
|
+
}
|
97
|
+
},
|
98
|
+
"/police" => [
|
99
|
+
{
|
100
|
+
header_clue: "There's no one answering, we have to go to the station...",
|
101
|
+
log_clue: "This status code is weird...",
|
102
|
+
body_clue: ""
|
103
|
+
},
|
104
|
+
{
|
105
|
+
header_clue: "They don't believe us. Or they don't want to know the truth.",
|
106
|
+
log_clue: "We have to go to /another_place",
|
107
|
+
body_clue: ""
|
108
|
+
}
|
109
|
+
],
|
110
|
+
"/another_place" => {
|
111
|
+
header_clue: "",
|
112
|
+
log_clue: "The dream held all the answers, we have to go back.",
|
113
|
+
body_clue: ""
|
114
|
+
}
|
115
|
+
|
116
|
+
# {
|
117
|
+
# url: "/coffee/?black=true",
|
118
|
+
# method: "delete",
|
119
|
+
# clue: "first character of every key in a hash",
|
120
|
+
# code: "cGo=" #pj
|
121
|
+
# },
|
122
|
+
# {
|
123
|
+
# url: "/ladies/?type=log",
|
124
|
+
# method: "get",
|
125
|
+
# clue: "all the odd elements in an array, after the array has been reversed",
|
126
|
+
# puzzle: [ "l", 119, "h", "MU", "G", "AT", "d", 145, "g", "ID", "4", "HQ", "W", "YY", "a", 404 ],
|
127
|
+
# code: "aW4gdGhl" # in the
|
128
|
+
# },
|
129
|
+
# {
|
130
|
+
# method: "get",
|
131
|
+
# url: "/meditations/type=mantra&eyes=closed",
|
132
|
+
# clue: "all numbers to `char` and all the letters to `ord`",
|
133
|
+
# puzzle: [99, 109, "\t", 118, 100, 67, 66, 107, 97, 88, 74, 108, 89, "\x03", 82, 118, 99, 110, 107, 61],
|
134
|
+
# code: "cm9vdCBkaXJlY3Rvcnk=" # root directory
|
135
|
+
# },
|
136
|
+
# {
|
137
|
+
# post: "[/owls]/7",
|
138
|
+
# data: { "eyes" => true },
|
139
|
+
# code: "d2l0aCB0aGU=" # with the
|
140
|
+
# },
|
141
|
+
# {
|
142
|
+
# url: "/gums/",
|
143
|
+
# method: "post",
|
144
|
+
# data: { news: "good", in_style: true },
|
145
|
+
# clue: "http://ruby-doc.org/stdlib-2.1.2/libdoc/base64/rdoc/Base64.html",
|
146
|
+
# code: "cm0gLXJm" # rm -rf
|
147
|
+
# }
|
148
|
+
}
|
149
|
+
|
150
|
+
#
|
151
|
+
# HINTS = [
|
152
|
+
# "I like Twin Peaks",
|
153
|
+
# "Join your hints together",
|
154
|
+
# "Try using query strings",
|
155
|
+
# "The owls have eyes",
|
156
|
+
# "Always check your headers"
|
157
|
+
# ]
|
158
|
+
end
|
metadata
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: another_place
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- phlco
|
8
|
+
- h4w5
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
@@ -19,12 +20,13 @@ extra_rdoc_files: []
|
|
19
20
|
files:
|
20
21
|
- bin/another_place
|
21
22
|
- lib/another_place/application/app.rb
|
22
|
-
- lib/another_place/application/
|
23
|
+
- lib/another_place/application/evidence.rb
|
23
24
|
homepage: http://rubygems.org/gems/another_place
|
24
25
|
licenses:
|
25
26
|
- MIT
|
26
27
|
metadata: {}
|
27
|
-
post_install_message:
|
28
|
+
post_install_message: Who killed Travis Vanderhoop? Run `another_place` to discover
|
29
|
+
this dark secret...
|
28
30
|
rdoc_options: []
|
29
31
|
require_paths:
|
30
32
|
- lib
|
@@ -1,68 +0,0 @@
|
|
1
|
-
module Clues
|
2
|
-
|
3
|
-
# header
|
4
|
-
# puzzle
|
5
|
-
# query
|
6
|
-
# puzzle
|
7
|
-
# data
|
8
|
-
# puzzle
|
9
|
-
|
10
|
-
CLUES = [
|
11
|
-
{
|
12
|
-
url: "/pies",
|
13
|
-
method: "get",
|
14
|
-
clue: "last character of every value in a hash",
|
15
|
-
puzzle: {
|
16
|
-
sushi: "tuna",
|
17
|
-
spice_level: "XX",
|
18
|
-
test: "IQ",
|
19
|
-
insect: "bug",
|
20
|
-
missing: "vitamin: d",
|
21
|
-
nosebleeds: "2",
|
22
|
-
nickname: "BIFF",
|
23
|
-
trailer: "zardoz"
|
24
|
-
},
|
25
|
-
code: "aXQgd2Fz"
|
26
|
-
# it was
|
27
|
-
},
|
28
|
-
{
|
29
|
-
url: "/coffee/?black=true",
|
30
|
-
method: "delete",
|
31
|
-
clue: "first character of every key in a hash",
|
32
|
-
code: "cGo=" #pj
|
33
|
-
},
|
34
|
-
{
|
35
|
-
url: "/ladies/?type=log",
|
36
|
-
method: "get",
|
37
|
-
clue: "all the odd elements in an array, reversed",
|
38
|
-
puzzle: [ "l", 119, "h", "MU", "G", "AT", "d", 145, "g", "ID", "4", "HQ", "W", "YY", "a", 404 ],
|
39
|
-
code: "aW4gdGhl" # in the
|
40
|
-
},
|
41
|
-
{
|
42
|
-
method: "get",
|
43
|
-
url: "/meditations/type=mantra&eyes=closed",
|
44
|
-
clue: "all numbers to `char` and all the letters to `ord`",
|
45
|
-
puzzle: [99, 109, "\t", 118, 100, 67, 66, 107, 97, 88, 74, 108, 89, "\x03", 82, 118, 99, 110, 107, 61],
|
46
|
-
code: "cm9vdCBkaXJlY3Rvcnk=" # root directory
|
47
|
-
},
|
48
|
-
{
|
49
|
-
post: "[/owls]/7",
|
50
|
-
data: { "eyes" => true },
|
51
|
-
code: "d2l0aCB0aGU=" # with the
|
52
|
-
},
|
53
|
-
{
|
54
|
-
url: "/gums/",
|
55
|
-
method: "post",
|
56
|
-
data: { news: "good", in_style: true },
|
57
|
-
clue: "http://ruby-doc.org/stdlib-2.1.2/libdoc/base64/rdoc/Base64.html",
|
58
|
-
code: "cm0gLXJm" # rm -rf
|
59
|
-
}
|
60
|
-
]
|
61
|
-
HINTS = [
|
62
|
-
"I like Twin Peaks",
|
63
|
-
"Join your hints together",
|
64
|
-
"Try using query strings",
|
65
|
-
"The owls have eyes",
|
66
|
-
"Always check your headers"
|
67
|
-
]
|
68
|
-
end
|