blob: 9f8e6261f82ee39c4c93c764ed26fc695665aba5 [file] [log] [blame]
Ed Tanousf9273472017-02-28 16:05:13 -08001#include "token_authorization_middleware.hpp"
2#include <crow/app.h>
3#include "gtest/gtest.h"
4
Ed Tanous8041f312017-04-03 09:47:01 -07005using namespace crow;
6using namespace std;
7
Ed Tanous1e94fa42017-04-03 13:41:19 -07008// Tests that static urls are correctly passed
9TEST(TokenAuthentication, TestBasicReject) {
10 App<crow::TokenAuthorizationMiddleware> app;
11 decltype(app)::server_t server(&app, "127.0.0.1", 45451);
12 CROW_ROUTE(app, "/")([]() { return 200; });
13 auto _ = async(launch::async, [&] { server.run(); });
14 asio::io_service is;
15 std::string sendmsg;
Ed Tanousf9273472017-02-28 16:05:13 -080016
Ed Tanous1e94fa42017-04-03 13:41:19 -070017 static char buf[2048];
Ed Tanousf9273472017-02-28 16:05:13 -080018
Ed Tanous1e94fa42017-04-03 13:41:19 -070019 // Homepage should be passed with no credentials
20 sendmsg = "GET /\r\n\r\n";
21 {
Ed Tanous8041f312017-04-03 09:47:01 -070022 asio::ip::tcp::socket c(is);
Ed Tanous1e94fa42017-04-03 13:41:19 -070023 c.connect(asio::ip::tcp::endpoint(
24 asio::ip::address::from_string("127.0.0.1"), 45451));
Ed Tanous8041f312017-04-03 09:47:01 -070025 c.send(asio::buffer(sendmsg));
26 auto received_count = c.receive(asio::buffer(buf, 2048));
27 c.close();
Ed Tanous1e94fa42017-04-03 13:41:19 -070028 EXPECT_EQ("200", std::string(buf + 9, buf + 12));
29 }
30
31 // static should be passed with no credentials
32 sendmsg = "GET /static/index.html\r\n\r\n";
33 {
34 asio::ip::tcp::socket c(is);
35 c.connect(asio::ip::tcp::endpoint(
36 asio::ip::address::from_string("127.0.0.1"), 45451));
37 c.send(asio::buffer(sendmsg));
38 c.receive(asio::buffer(buf, 2048));
39 c.close();
40 EXPECT_EQ("404", std::string(buf + 9, buf + 12));
41 }
42
43 server.stop();
44}
45
46// Tests that Base64 basic strings work
47TEST(TokenAuthentication, TestRejectedResource) {
48 App<crow::TokenAuthorizationMiddleware> app;
49 app.bindaddr("127.0.0.1").port(45451);
50 CROW_ROUTE(app, "/")([]() { return 200; });
51 auto _ = async(launch::async, [&] { app.run(); });
52
53 asio::io_service is;
54 static char buf[2048];
55
56 // Other resources should not be passed
57 std::string sendmsg = "GET /foo\r\n\r\n";
58 asio::ip::tcp::socket c(is);
59 for (int i = 0; i < 200; i++) {
60 try {
61 c.connect(asio::ip::tcp::endpoint(
62 asio::ip::address::from_string("127.0.0.1"), 45451));
63 } catch (std::exception e) {
64 // do nothing
65 }
66 }
67 c.send(asio::buffer(sendmsg));
68 auto received_count = c.receive(asio::buffer(buf, 2048));
69 c.close();
70 EXPECT_EQ("401", std::string(buf + 9, buf + 12));
71
72 app.stop();
73}
74
75// Tests that Base64 basic strings work
76TEST(TokenAuthentication, TestGetLoginUrl) {
77 App<crow::TokenAuthorizationMiddleware> app;
78 app.bindaddr("127.0.0.1").port(45451);
79 CROW_ROUTE(app, "/")([]() { return 200; });
80 auto _ = async(launch::async, [&] { app.run(); });
81
82 asio::io_service is;
83 static char buf[2048];
84
85 // Other resources should not be passed
86 std::string sendmsg = "GET /login\r\n\r\n";
87 asio::ip::tcp::socket c(is);
88 for (int i = 0; i < 200; i++) {
89 try {
90 c.connect(asio::ip::tcp::endpoint(
91 asio::ip::address::from_string("127.0.0.1"), 45451));
92 } catch (std::exception e) {
93 // do nothing
94 }
95 }
96 c.send(asio::buffer(sendmsg));
97 auto received_count = c.receive(asio::buffer(buf, 2048));
98 c.close();
99 EXPECT_EQ("401", std::string(buf + 9, buf + 12));
100
101 app.stop();
102}
103
104// Tests boundary conditions on login
105TEST(TokenAuthentication, TestPostBadLoginUrl) {
106 App<crow::TokenAuthorizationMiddleware> app;
107 app.bindaddr("127.0.0.1").port(45451);
108 CROW_ROUTE(app, "/")([]() { return 200; });
109 auto _ = async(launch::async, [&] { app.run(); });
110
111 asio::io_service is;
112 std::array<char, 2048> buf;
113 std::string sendmsg;
114
115 auto send_to_localhost = [&is, &buf](std::string sendmsg) {
116 asio::ip::tcp::socket c(is);
117 c.connect(asio::ip::tcp::endpoint(
118 asio::ip::address::from_string("127.0.0.1"), 45451));
119 c.send(asio::buffer(sendmsg));
120 auto received_count = c.receive(asio::buffer(buf));
121 c.close();
122 };
123
124 {
125 // Retry a couple of times waiting for the server to come up
126 asio::ip::tcp::socket c(is);
127 for (int i = 0; i < 200; i++) {
128 try {
129 c.connect(asio::ip::tcp::endpoint(
130 asio::ip::address::from_string("127.0.0.1"), 45451));
131 c.close();
132 break;
133 } catch (std::exception e) {
134 // do nothing. We expect this to fail while the server is starting up
135 }
136 }
137 }
138
139 // Test blank login credentials
140 sendmsg = "POST /login\r\nContent-Length:0\r\n\r\n\r\n";
141 {
142 send_to_localhost(sendmsg);
143 auto return_code = std::string(&buf[9], &buf[12]);
144 EXPECT_EQ("400", return_code);
145 }
146
147 // Test wrong login credentials
148 sendmsg =
149 "POST /login\r\nContent-Length:38\r\n\r\n{\"username\": \"foo\", "
150 "\"password\": \"bar\"}\r\n";
151 {
152 send_to_localhost(sendmsg);
153 auto return_code = std::string(&buf[9], &buf[12]);
154 EXPECT_EQ("401", return_code);
155 // TODO(ed) need to test more here. Response string?
156 }
157
158 // Test only sending a username
159 sendmsg =
160 "POST /login\r\nContent-Length:19\r\n\r\n{\"username\": \"foo\"}\r\n";
161 {
162 send_to_localhost(sendmsg);
163 auto return_code = std::string(&buf[9], &buf[12]);
164 EXPECT_EQ("400", return_code);
165 }
166
167 // Test only sending a password
168 sendmsg =
169 "POST /login\r\nContent-Length:19\r\n\r\n{\"password\": \"foo\"}\r\n";
170 {
171 send_to_localhost(sendmsg);
172 auto return_code = std::string(&buf[9], &buf[12]);
173 EXPECT_EQ("400", return_code);
174 }
175
176 app.stop();
177}
178
179// Tests boundary conditions on login
180TEST(TokenAuthentication, TestSuccessfulLogin) {
181 App<crow::TokenAuthorizationMiddleware> app;
182 app.bindaddr("127.0.0.1").port(45451);
183 CROW_ROUTE(app, "/")([]() { return 200; });
184 auto _ = async(launch::async, [&] { app.run(); });
185
186 asio::io_service is;
187 std::array<char, 2048> buf;
188 std::string sendmsg;
189
190 auto send_to_localhost = [&is, &buf](std::string sendmsg) {
191 asio::ip::tcp::socket c(is);
192 c.connect(asio::ip::tcp::endpoint(
193 asio::ip::address::from_string("127.0.0.1"), 45451));
194 c.send(asio::buffer(sendmsg));
195 auto received_count = c.receive(asio::buffer(buf));
196 c.close();
197 };
198
199 {
200 // Retry a couple of times waiting for the server to come up
201 asio::ip::tcp::socket c(is);
202 for (int i = 0; i < 200; i++) {
203 try {
204 c.connect(asio::ip::tcp::endpoint(
205 asio::ip::address::from_string("127.0.0.1"), 45451));
206 c.close();
207 break;
208 } catch (std::exception e) {
209 // do nothing. We expect this to fail while the server is starting up
210 }
211 }
212 }
213
214 // Test correct login credentials
215 sendmsg =
216 "POST /login\r\nContent-Length:40\r\n\r\n{\"username\": \"dude\", "
217 "\"password\": \"dude\"}\r\n";
218 {
219 send_to_localhost(sendmsg);
220 auto return_code = std::string(&buf[9], &buf[12]);
221 EXPECT_EQ("200", return_code);
222 }
223
224
225 // Try to use those login credentials to access a resource
226 sendmsg =
227 "GET /\r\nAuthorization: token\r\n\r\n{\"username\": \"dude\", "
228 "\"password\": \"dude\"}\r\n";
229 {
230 send_to_localhost(sendmsg);
231 auto return_code = std::string(&buf[9], &buf[12]);
232 EXPECT_EQ("200", return_code);
233 }
234
235 app.stop();
Ed Tanous8041f312017-04-03 09:47:01 -0700236}